javassist.util.proxy
Class ProxyFactory

java.lang.Object
  extended by javassist.util.proxy.ProxyFactory

public class ProxyFactory
extends java.lang.Object

Factory of dynamic proxy classes.

This factory generates a class that extends the given super class and implements the given interfaces. The calls of the methods inherited from the super class are forwarded and then invoke() is called on the method handler associated with instances of the generated class. The calls of the methods from the interfaces are also forwarded to the method handler.

For example, if the following code is executed,

Then, the following method call will be forwarded to MethodHandler mi and prints a message before executing the originally called method bar() in Foo.

The last three lines of the code shown above can be replaced with a call to the helper method create, which generates a proxy class, instantiates it, and sets the method handler of the instance:

To change the method handler during runtime, execute the following code:

If setHandler is never called for a proxy instance then it will employ the default handler which proceeds by invoking the original method. The behaviour of the default handler is identical to the following handler:

A proxy factory caches and reuses proxy classes by default. It is possible to reset this default globally by setting static field useCache to false. Caching may also be configured for a specific factory by calling instance method setUseCache(boolean). It is strongly recommended that new clients of class ProxyFactory enable caching. Failure to do so may lead to exhaustion of the heap memory area used to store classes.

Caching is automatically disabled for any given proxy factory if deprecated instance method setHandler(MethodHandler) is called. This method was used to specify a default handler which newly created proxy classes should install when they create their instances. It is only retained to provide backward compatibility with previous releases of javassist. Unfortunately,this legacy behaviour makes caching and reuse of proxy classes impossible. The current programming model expects javassist clients to set the handler of a proxy instance explicitly by calling method ProxyObject.setHandler(MethodHandler) as shown in the sample code above. New clients are strongly recommended to use this model rather than calling setHandler(MethodHandler).

A proxy object generated by ProxyFactory is serializable if its super class or any of its interfaces implement java.io.Serializable. However, a serialized proxy object may not be compatible with future releases. The serialization support should be used for short-term storage or RMI.

For compatibility with older releases serialization of proxy objects is implemented by adding a writeReplace method to the proxy class. This allows a proxy to be serialized to a conventional ObjectOutputStream and deserialized from a corresponding ObjectInputStream. However this method suffers from several problems, the most notable one being that it fails to serialize state inherited from the proxy's superclass.

An alternative method of serializing proxy objects is available which fixes these problems. It requires inhibiting generation of the writeReplace method and instead using instances of ProxyObjectOutputStream and ProxyObjectInputStream (which are subclasses of ObjectOutputStream and ObjectInputStream) to serialize and deserialize, respectively, the proxy. These streams recognise javassist proxies and ensure that they are serialized and deserialized without the need for the proxy class to implement special methods such as writeReplace. Generation of the writeReplace method can be disabled globally by setting static field useWriteReplace to false. Alternatively, it may be configured per factory by calling instance method setUseWriteReplace(boolean).

Since:
3.1
Author:
Muga Nishizawa, Shigeru Chiba, Andrew Dinn
See Also:
MethodHandler

Nested Class Summary
static interface ProxyFactory.ClassLoaderProvider
          A provider of class loaders.
 
Field Summary
static ProxyFactory.ClassLoaderProvider classLoaderProvider
          A provider used by createClass() for obtaining a class loader.
static boolean useCache
          If true, a generated proxy class is cached and it will be reused when generating the proxy class with the same properties is requested.
static boolean useWriteReplace
          If true, a generated proxy class will implement method writeReplace enabling serialization of its proxies to a conventional ObjectOutputStream.
 java.lang.String writeDirectory
          If the value of this variable is not null, the class file of the generated proxy class is written under the directory specified by this variable.
 
Constructor Summary
ProxyFactory()
          Constructs a factory of proxy class.
 
Method Summary
 java.lang.Object create(java.lang.Class[] paramTypes, java.lang.Object[] args)
          Creates a proxy class and returns an instance of that class.
 java.lang.Object create(java.lang.Class[] paramTypes, java.lang.Object[] args, MethodHandler mh)
          Creates a proxy class and returns an instance of that class.
 java.lang.Class createClass()
          Generates a proxy class using the current filter.
 java.lang.Class createClass(MethodFilter filter)
          Generates a proxy class using the supplied filter.
 java.lang.Class[] getInterfaces()
          Obtains the interfaces set by setInterfaces.
 java.lang.String getKey(java.lang.Class superClass, java.lang.Class[] interfaces, byte[] signature, boolean useWriteReplace)
           
 java.lang.Class getSuperclass()
          Obtains the super class set by setSuperclass().
static boolean isProxyClass(java.lang.Class cl)
          determine if a class is a javassist proxy class
 boolean isUseCache()
          test whether this factory uses the proxy cache
 boolean isUseWriteReplace()
          test whether this factory installs a writeReplace method in created classes
 void setFilter(MethodFilter mf)
          Sets a filter that selects the methods that will be controlled by a handler.
 void setHandler(MethodHandler mi)
          Deprecated. since 3.12 use of this method is incompatible with proxy class caching. instead clients should call method ProxyObject.setHandler(MethodHandler) to set the handler for each newly created proxy instance. calling this method will automatically disable caching of classes created by the proxy factory.
 void setInterfaces(java.lang.Class[] ifs)
          Sets the interfaces of a proxy class.
 void setSuperclass(java.lang.Class clazz)
          Sets the super class of a proxy class.
 void setUseCache(boolean useCache)
          configure whether this factory should use the proxy cache
 void setUseWriteReplace(boolean useWriteReplace)
          configure whether this factory should add a writeReplace method to created classes
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

writeDirectory

public java.lang.String writeDirectory
If the value of this variable is not null, the class file of the generated proxy class is written under the directory specified by this variable. For example, if the value is ".", then the class file is written under the current directory. This method is for debugging.

The default value is null.


useCache

public static volatile boolean useCache
If true, a generated proxy class is cached and it will be reused when generating the proxy class with the same properties is requested. The default value is true. Note that this value merely specifies the initial setting employed by any newly created proxy factory. The factory setting may be overwritten by calling factory instance method setUseCache(boolean)

Since:
3.4

useWriteReplace

public static volatile boolean useWriteReplace
If true, a generated proxy class will implement method writeReplace enabling serialization of its proxies to a conventional ObjectOutputStream. this (default) setting retains the old javassist behaviour which has the advantage that it retains compatibility with older releases and requires no extra work on the part of the client performing the serialization. However, it has the disadvantage that state inherited from the superclasses of the proxy is lost during serialization. if false then serialization/deserialization of the proxy instances will preserve all fields. However, serialization must be performed via a ProxyObjectOutputStream and deserialization must be via ProxyObjectInputStream. Any attempt to serialize proxies whose class was created with useWriteReplace set to false via a normal ObjectOutputStream will fail. Note that this value merely specifies the initial setting employed by any newly created proxy factory. The factory setting may be overwritten by calling factory instance method setUseWriteReplace(boolean)

Since:
3.4

classLoaderProvider

public static ProxyFactory.ClassLoaderProvider classLoaderProvider
A provider used by createClass() for obtaining a class loader. get() on this ClassLoaderProvider object is called to obtain a class loader.

The value of this field can be updated for changing the default implementation.

Example:

Since:
3.4
Constructor Detail

ProxyFactory

public ProxyFactory()
Constructs a factory of proxy class.

Method Detail

isUseCache

public boolean isUseCache()
test whether this factory uses the proxy cache

Returns:
true if this factory uses the proxy cache otherwise false

setUseCache

public void setUseCache(boolean useCache)
configure whether this factory should use the proxy cache

Parameters:
useCache - true if this factory should use the proxy cache and false if it should not use the cache
Throws:
java.lang.RuntimeException - if a default interceptor has been set for the factory

isUseWriteReplace

public boolean isUseWriteReplace()
test whether this factory installs a writeReplace method in created classes

Returns:
true if this factory installs a writeReplace method in created classes otherwise false

setUseWriteReplace

public void setUseWriteReplace(boolean useWriteReplace)
configure whether this factory should add a writeReplace method to created classes

Parameters:
useWriteReplace - true if this factory should add a writeReplace method to created classes and false if it should not add a writeReplace method

isProxyClass

public static boolean isProxyClass(java.lang.Class cl)
determine if a class is a javassist proxy class

Parameters:
cl -
Returns:
true if the class is a javassist proxy class otherwise false

setSuperclass

public void setSuperclass(java.lang.Class clazz)
Sets the super class of a proxy class.


getSuperclass

public java.lang.Class getSuperclass()
Obtains the super class set by setSuperclass().

Since:
3.4

setInterfaces

public void setInterfaces(java.lang.Class[] ifs)
Sets the interfaces of a proxy class.


getInterfaces

public java.lang.Class[] getInterfaces()
Obtains the interfaces set by setInterfaces.

Since:
3.4

setFilter

public void setFilter(MethodFilter mf)
Sets a filter that selects the methods that will be controlled by a handler.


createClass

public java.lang.Class createClass()
Generates a proxy class using the current filter.


createClass

public java.lang.Class createClass(MethodFilter filter)
Generates a proxy class using the supplied filter.


getKey

public java.lang.String getKey(java.lang.Class superClass,
                               java.lang.Class[] interfaces,
                               byte[] signature,
                               boolean useWriteReplace)

create

public java.lang.Object create(java.lang.Class[] paramTypes,
                               java.lang.Object[] args,
                               MethodHandler mh)
                        throws java.lang.NoSuchMethodException,
                               java.lang.IllegalArgumentException,
                               java.lang.InstantiationException,
                               java.lang.IllegalAccessException,
                               java.lang.reflect.InvocationTargetException
Creates a proxy class and returns an instance of that class.

Parameters:
paramTypes - parameter types for a constructor.
args - arguments passed to a constructor.
mh - the method handler for the proxy class.
Throws:
java.lang.NoSuchMethodException
java.lang.IllegalArgumentException
java.lang.InstantiationException
java.lang.IllegalAccessException
java.lang.reflect.InvocationTargetException
Since:
3.4

create

public java.lang.Object create(java.lang.Class[] paramTypes,
                               java.lang.Object[] args)
                        throws java.lang.NoSuchMethodException,
                               java.lang.IllegalArgumentException,
                               java.lang.InstantiationException,
                               java.lang.IllegalAccessException,
                               java.lang.reflect.InvocationTargetException
Creates a proxy class and returns an instance of that class.

Parameters:
paramTypes - parameter types for a constructor.
args - arguments passed to a constructor.
Throws:
java.lang.NoSuchMethodException
java.lang.IllegalArgumentException
java.lang.InstantiationException
java.lang.IllegalAccessException
java.lang.reflect.InvocationTargetException

setHandler

public void setHandler(MethodHandler mi)
Deprecated. since 3.12 use of this method is incompatible with proxy class caching. instead clients should call method ProxyObject.setHandler(MethodHandler) to set the handler for each newly created proxy instance. calling this method will automatically disable caching of classes created by the proxy factory.

Sets the default invocation handler. This invocation handler is shared among all the instances of a proxy class unless another is explicitly specified.



Javassist, a Java-bytecode translator toolkit.
Copyright (C) 1999-2010 Shigeru Chiba. All Rights Reserved.