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,
ProxyFactory f = new ProxyFactory();
f.setSuperclass(Foo.class);
f.setFilter(new MethodFilter() {
public boolean isHandled(Method m) {
// ignore finalize()
return !m.getName().equals("finalize");
}
});
Class c = f.createClass();
MethodHandler mi = new MethodHandler() {
public Object invoke(Object self, Method m, Method proceed,
Object[] args) throws Throwable {
System.out.println("Name: " + m.getName());
return proceed.invoke(self, args); // execute the original method.
}
};
Foo foo = (Foo)c.newInstance();
((Proxy)foo).setHandler(mi);
Here, Method is java.lang.reflect.Method.
Then, the following method call will be forwarded to MethodHandler
mi and prints a message before executing the originally called method
bar() in Foo.
foo.bar();
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:
:
Foo foo = (Foo)f.create(new Class[0], new Object[0], mi);
To change the method handler during runtime, execute the following code:
MethodHandler mi = ... ; // alternative handler ((Proxy)foo).setHandler(mi);
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:
class EmptyHandler implements MethodHandler {
public Object invoke(Object self, Method m,
Method proceed, Object[] args) throws Exception {
return proceed.invoke(self, args);
}
}
A proxy factory caches and reuses proxy classes by default. It is possible to reset
this default globally by setting static field ProxyFactory#useCache to false.
Caching may also be configured for a specific factory by calling instance method
ProxyFactory#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 ProxyFactory#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
Proxy#setHandler(MethodHandler) as shown in the sample code above. New
clients are strongly recommended to use this model rather than calling
ProxyFactory#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 java. and deserialized from a corresponding
java.. 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
javassist. and javassist.
(which are subclasses of java. and java.)
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
ProxyFactory#useWriteReplace to false. Alternatively, it may be
configured per factory by calling instance method ProxyFactory#setUseWriteReplace(boolean).
MethodHandler
| Modifier and Type | Class and Description |
|---|---|
| public static interface | ProxyFactory.
A provider of class loaders. |
| pack-priv static class | |
| pack-priv static class | ProxyFactory.
used to store details of a specific proxy class in the second tier of the proxy cache. |
| public static interface | ProxyFactory.
A unique class name generator. |
| Modifier and Type | Field and Description |
|---|---|
| private String | |
| public static ProxyFactory. | classLoaderProvider
A provider used by |
| private String | |
| private static final String | |
| private boolean | factoryUseCache
per factory setting initialised from current setting for useCache but able to be reset before each create call |
| private boolean | factoryWriteReplace
per factory setting initialised from current setting for useWriteReplace but able to be reset before each create call |
| private static final String | |
| private static final String | |
| private String | |
| private MethodHandler | |
| private static final String | |
| private static final String | |
| private static final String | |
| private static final String | |
| private static final String | |
| private static final String | |
| private static final String | |
| private boolean | |
| private static char[] | |
| private static final String | |
| private static final String | |
| private Class | |
| private MethodFilter | |
| public static ProxyFactory. | nameGenerator
A unique class name generator. |
| private static final String | |
| private static final Class | |
| public static boolean | onlyPublicMethods
If true, only public/protected methods are forwarded to a proxy object. |
| private static final String | |
| private static Map | |
| private static final String | |
| private static final String | |
| private static final long | |
| private byte[] | |
| private List | |
| private static Comparator | |
| private Class | |
| private String | |
| private Class | |
| 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. |
| public static volatile boolean | useWriteReplace
If true, a generated proxy class will implement method writeReplace enabling serialization of its proxies to a conventional ObjectOutputStream. |
| public 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. |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| private static void | addClassInitializer(ClassFile cf, ConstPool cp, String classname, int size, List<ProxyFactory.
|
| private static void | |
| private static int | |
| private static int | |
| private static int | |
| private static void | |
| private static void | |
| private void | |
| private static boolean | |
| private static void | callFind2Methods(Bytecode code, String superMethod, String
might be null. thisMethod, int index, String desc, int classVar, int arrayVar)
|
| private void | |
| private void | |
| public Object | create(Class<?>[]
parameter types for a constructor. paramTypes, Object[] arguments passed to a constructor. args, MethodHandler the method handler for the proxy class. mh)Creates a proxy class and returns an instance of that class. |
| public Object | |
| public Class | |
| public Class | |
| pack-priv Class | |
| public Class | createClass(MethodHandles.
used for loading the proxy class.
It needs an appropriate right to invoke lookupdefineClass
for the proxy class.Generates a proxy class using the current filter. |
| public Class | createClass(MethodHandles.
used for loading the proxy class.
It needs an appropriate right to invoke lookup,defineClass
for the proxy class.the filter. filter)Generates a proxy class using the supplied filter. |
| pack-priv Class | createClass(MethodHandles.
used for loading the proxy class.
It needs an appropriate right to invoke lookup,defineClass
for the proxy class.the signature. signature)Generates a proxy class with a specific signature. |
| private Class | |
| private void | |
| private void | |
| private Class | getClassInTheSamePackage()
Obtains a class belonging to the same package that the created proxy class belongs to. |
| protected ClassLoader | |
| protected ClassLoader | |
| protected ProtectionDomain | |
| private static Object | |
| pack-priv static byte[] | |
| public static MethodHandler | Returns: the method handler.a proxy object. p)Obtains the method handler of the given proxy object. |
| public Class | |
| public String | |
| private Map | |
| private void | |
| private static String | |
| public Class | |
| private void | |
| private Class | |
| private static boolean | |
| private static boolean | |
| public static boolean | Returns: true if the class is a javassist proxy class otherwise falsedetermine if a class is a javassist proxy class |
| public boolean | Returns: true if this factory uses the proxy cache otherwise falsetest whether this factory uses the proxy cache |
| public boolean | Returns: true if this factory installs a writeReplace method in created classes otherwise falsetest whether this factory installs a writeReplace method in created classes |
| private static boolean | |
| private static String | |
| private ClassFile | |
| private static MethodInfo | makeConstructor(String thisClassName, Constructor<?> cons, ConstPool cp, Class<?> superClass, boolean doHandlerInit)
|
| private void | |
| private MethodInfo | |
| private static MethodInfo | makeForwarder(String thisClassName, Method meth, String desc, ConstPool cp, Class<?> declClass, String
null if the original method is abstract. delegatorName, int index, List<ProxyFactory.
|
| private static void | |
| private static String | |
| private void | |
| private static String | |
| private static boolean | |
| private static int | |
| private static MethodInfo | |
| private void | override(String thisClassname, Method meth, String prefix, int index, String desc, ClassFile cf, ConstPool cp, List<ProxyFactory.
|
| private int | overrideMethods(ClassFile cf, ConstPool cp, String className, List<ProxyFactory.
|
| private void | |
| private void | |
| public void | setFilter(MethodFilter mf)
Sets a filter that selects the methods that will be controlled by a handler. |
| public void | |
| public void | setHandler(MethodHandler mi)
Deprecated
since 3.12
use of this method is incompatible with proxy class caching.
Sets the default invocation handler. |
| public void | |
| private static void | |
| public void | |
| private static void | |
| private static void | |
| public void | setUseCache(boolean
true if this factory should use the proxy cache and false if it should not use the cache useCache)configure whether this factory should use the proxy cache |
| public void | setUseWriteReplace(boolean
true if this factory should add a writeReplace method to created classes and false if it
should not add a writeReplace method useWriteReplace)configure whether this factory should add a writeReplace method to created classes |
| private boolean |