public final class ProxyFactory
extends java.lang.Object
ProxyAssembler. Please see the description of that class for the
rationale of this mechanism as an alternative to Java's standard, dynamic
proxy implementation.
The access points to this factory's functionality are the public, static
variants of the getProxy method, which allow the definition
of a new proxy class, based on a given superclass, list of interfaces to
implement, and an invocation handler to which method invocations are
dispatched. Several additional options are available to tailor the proxy
class to specific needs. Please see:
| Modifier and Type | Class and Description |
|---|---|
static class |
ProxyFactory.CacheKey
A cache key which takes into account a proxy class' parent, implemented
interfaces, whether only declared methods are implemented, and list of
methods to be omitted from the proxy.
|
| Modifier and Type | Field and Description |
|---|---|
private java.util.Map<ProxyFactory.CacheKey,java.lang.ref.WeakReference<java.lang.Class<?>>> |
cache
Cache of proxy classes which already have been assembled
|
private java.util.Map<java.lang.Class<?>,java.lang.reflect.Constructor<?>> |
classCtors
Cache the target constructor for each proxy class.
|
private AsmClassLoader |
loader
Custom class loader to load proxy classes
|
private static CentralLogger |
log
Logger
|
private static boolean |
LOG_FINE
Do we log FINE-level events ?
|
private static boolean |
LOG_INFO
Do we log INFO-level events ?
|
private static boolean |
LOG_WARNING
Do we log WARNING-level events ?
|
private int |
nextSuffix
Suffix to ensure unique proxy class names
|
private static java.lang.reflect.Method[] |
NULL_DO_NOT_PROXY
Singleton to identify the hash for a null 'doNotProxy' parameter.
|
private static java.util.Set<java.lang.Class<?>> |
parentsOfPregeneratedProxies
Set containing the parent classes of any proxy that might be pre-generated.
|
private java.util.Map<java.lang.String,java.lang.String> |
pregeneratedCache
Mapping of a string representation of a
ProxyFactory.CacheKey to the name of pregenerated proxy class. |
private static ProxyFactory |
singleton
Singleton instance of this factory class
|
private boolean |
usePregeneratedProxies
Flag used to mark whether the server should use the pre-generated proxy classes.
|
| Modifier | Constructor and Description |
|---|---|
private |
ProxyFactory()
Private constructor to ensure singleton instance.
|
| Modifier and Type | Method and Description |
|---|---|
private java.lang.reflect.Method[] |
gatherMethods(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy)
Gather the final list of methods to be implemented explicitly by the
dynamic proxy class.
|
static <T> T |
getProxy(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin,
java.lang.reflect.InvocationHandler handler)
Get an instance of a proxy class which subclasses the given parent class
and implements the specified interfaces.
|
static <T> T |
getProxy(java.lang.Class<?> parent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin,
java.lang.reflect.InvocationHandler handler)
Get an instance of a proxy class which subclasses the given parent class
and implements the specified interfaces.
|
static <T> T |
getProxy(java.lang.Class<?> parent,
java.lang.Class<?>[] interfaces,
java.lang.reflect.InvocationHandler handler)
Get an instance of a proxy class which subclasses the given parent class
and implements the specified interfaces.
|
static <T> T |
getProxy(java.lang.Class<? extends java.lang.reflect.InvocationHandler> parent,
java.lang.Class<?>[] interfaces)
Get an instance of a proxy class which subclasses the given parent class
and implements the specified interfaces.
|
static <T> T |
getProxy(java.lang.Class<? extends java.lang.reflect.InvocationHandler> parent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy)
Get an instance of a proxy class which subclasses the given parent class
and implements the specified interfaces.
|
static ProxyAssembler |
getProxyAssembler(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
boolean proxyIsHandler,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin)
Create a proxy assembler and return it.
|
private <T> T |
getProxyImpl(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin,
java.lang.reflect.InvocationHandler handler)
Get an instance of a proxy class which subclasses the given parent class
and implements the specified interfaces.
|
private java.lang.reflect.Method |
identifyBestMethod(java.util.Set<java.lang.reflect.Method> methods)
Given a set of methods, identify the best method to implement in the
dynamic proxy.
|
static boolean |
isProxyClass(java.lang.Class<?> clazz)
Indicate whether the given class represents a proxy class generated by
this factory.
|
private void |
loadPregeneratedCacheData()
This method is responsible for reading the pre-generated proxies cache
from disk, saving it to the
pregeneratedCache map and updating nextSuffix. |
private java.lang.String |
makeProxyClassName(java.lang.Class<?> parent,
java.lang.String parentName)
Given the proxy's superclass and its name, generate a unique name of the
proxy class, which can be used to load the class in the custom, proxy
class loader.
|
private static final java.lang.reflect.Method[] NULL_DO_NOT_PROXY
private static final ProxyFactory singleton
private static final CentralLogger log
private static final boolean LOG_WARNING
private static final boolean LOG_INFO
private static final boolean LOG_FINE
private final java.util.Map<ProxyFactory.CacheKey,java.lang.ref.WeakReference<java.lang.Class<?>>> cache
private final java.util.Map<java.lang.Class<?>,java.lang.reflect.Constructor<?>> classCtors
private final AsmClassLoader loader
private int nextSuffix
private java.util.Map<java.lang.String,java.lang.String> pregeneratedCache
ProxyFactory.CacheKey to the name of pregenerated proxy class.private static java.util.Set<java.lang.Class<?>> parentsOfPregeneratedProxies
private boolean usePregeneratedProxies
private ProxyFactory()
private void loadPregeneratedCacheData()
pregeneratedCache map and updating nextSuffix.public static ProxyAssembler getProxyAssembler(java.lang.Class<?> parent, boolean proxyParent, java.lang.Class<?>[] interfaces, boolean declaredOnly, java.lang.reflect.Method[] doNotProxy, boolean proxyIsHandler, java.util.function.Supplier<ProxyAssemblerPlugin> plugin)
parent - Superclass of the proxy class.proxyParent - Flag indicating that all public and protected parent class methods will be proxied.interfaces - Array of interfaces which must be implemented by the proxy class.declaredOnly - If true, only methods explicitly declared by the
given interfaces are used; if false, methods
declared by the given interfaces and by any of their ancestor
interfaces are used.doNotProxy - An optional array of Method objects which are not
to be implemented by the dynamically generated proxy. This
option should be used only to represent methods which already
are implemented by the proxy class' superclass.proxyIsHandler - true if the parent class implements the nvocationHandler
interface, else false. If true, no separate instance
field will be assembled to store the invocation handler reference, as the instance
of this class itself will act as the handler.plugin - An optional plugin which can override the assembly of arbitrary methods.public static <T> T getProxy(java.lang.Class<?> parent,
java.lang.Class<?>[] interfaces,
java.lang.reflect.InvocationHandler handler)
If a proxy class does not yet exist which meets the given criteria, one is assembled and loaded on the fly.
Implementation Note: if multiple interfaces specify methods with the same names, compatible signatures and return types, but different lists of exception types, the first method discovered which has a return type assignable from all other, matching methods is used for the dynamic proxy, regardless of the exception list. Therefore, callers should take care to specify methods with matching exception lists, if methods with the same name, signature, and compatible return types are specified across interfaces.
T - Type of the proxy class which will be returned.parent - Superclass of the proxy class.interfaces - Array of interfaces which must be implemented by the proxy
class.handler - Handler to which to dispatch method invocations.parent and which implements the
methods defined by interfaces.java.lang.IllegalArgumentException - if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types.public static <T> T getProxy(java.lang.Class<?> parent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin,
java.lang.reflect.InvocationHandler handler)
If a proxy class does not yet exist which meets the given criteria, one is assembled and loaded on the fly.
Implementation Note: if multiple interfaces specify methods with compatible signatures and return types, but different lists of exception types, the first method discovered which has a return type which is assignable from all other, matching methods is used for the dynamic proxy, regardless of the exception list. The order in which methods are checked is indeterminate. Therefore, callers should be careful to specify methods with matching exception lists, if methods with the same name, signature, and compatible return types are specified across interfaces.
T - Type of the proxy class which will be returned.parent - Superclass of the proxy class.interfaces - Array of interfaces which must be implemented by the proxy
class.declaredOnly - If true, only methods explicitly declared by the
given interfaces are used; if false, methods
declared by the given interfaces and by any of their ancestor
interfaces are used.doNotProxy - An optional array of Method objects which are not
to be implemented by the dynamically generated proxy. This
option should be used only to represent methods which already
are implemented by the proxy class' superclass.handler - Handler to which to dispatch method invocations. This value
must not be null.parent and which implements the
methods defined by interfaces.java.lang.IllegalArgumentException - if handler is null;
if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types.public static <T> T getProxy(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin,
java.lang.reflect.InvocationHandler handler)
If a proxy class does not yet exist which meets the given criteria, one is assembled and loaded on the fly.
Implementation Note: if multiple interfaces specify methods with compatible signatures and return types, but different lists of exception types, the first method discovered which has a return type which is assignable from all other, matching methods is used for the dynamic proxy, regardless of the exception list. The order in which methods are checked is indeterminate. Therefore, callers should be careful to specify methods with matching exception lists, if methods with the same name, signature, and compatible return types are specified across interfaces.
T - Type of the proxy class which will be returned.parent - Superclass of the proxy class.proxyParent - Flag indicating that all public and protected parent class methods will be proxied.interfaces - Array of interfaces which must be implemented by the proxy
class.declaredOnly - If true, only methods explicitly declared by the
given interfaces are used; if false, methods
declared by the given interfaces and by any of their ancestor
interfaces are used.doNotProxy - An optional array of Method objects which are not
to be implemented by the dynamically generated proxy. This
option should be used only to represent methods which already
are implemented by the proxy class' superclass.handler - Handler to which to dispatch method invocations. This value
must not be null.parent and which implements the
methods defined by interfaces.java.lang.IllegalArgumentException - if handler is null;
if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types.public static <T> T getProxy(java.lang.Class<? extends java.lang.reflect.InvocationHandler> parent,
java.lang.Class<?>[] interfaces)
InvocationHandler instance. It should be used
when the parent class is expected to fulfill the role of invocation
handler.
If a proxy class does not yet exist which meets the given criteria, one is assembled and loaded on the fly.
Implementation Note: if multiple interfaces specify methods with compatible signatures and return types, but different lists of exception types, the first method discovered which has a return type which is assignable from all other, matching methods is used for the dynamic proxy, regardless of the exception list. The order in which methods are checked is indeterminate. Therefore, callers should be careful to specify methods with matching exception lists, if methods with the same name, signature, and compatible return types are specified across interfaces.
T - Type of the proxy class which will be returned.parent - Superclass of the proxy class, which must implement the
InvocationHandler interface.interfaces - Array of interfaces which must be implemented by the proxy
class.parent and which implements the
methods defined by interfaces.java.lang.IllegalArgumentException - if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types.public static <T> T getProxy(java.lang.Class<? extends java.lang.reflect.InvocationHandler> parent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy)
InvocationHandler instance. It should be used
when the parent class is expected to fulfill the role of invocation
handler.
If a proxy class does not yet exist which meets the given criteria, one is assembled and loaded on the fly.
Implementation Note: if multiple interfaces specify methods with compatible signatures and return types, but different lists of exception types, the first method discovered which has a return type which is assignable from all other, matching methods is used for the dynamic proxy, regardless of the exception list. The order in which methods are checked is indeterminate. Therefore, callers should be careful to specify methods with matching exception lists, if methods with the same name, signature, and compatible return types are specified across interfaces.
T - Type of the proxy class which will be returned.parent - Superclass of the proxy class, which must implement the
InvocationHandler interface.interfaces - Array of interfaces which must be implemented by the proxy
class.declaredOnly - If true, only methods explicitly declared by the
given interfaces are used; if false, methods
declared by the given interfaces and by any of their ancestor
interfaces are used.doNotProxy - An optional array of Method objects which are not
to be implemented by the dynamically generated proxy. This
option should be used only to represent methods which already
are implemented by the proxy class' superclass.parent and which implements the
methods defined by interfaces.java.lang.IllegalArgumentException - if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types.public static boolean isProxyClass(java.lang.Class<?> clazz)
clazz - The class to be tested.true if the given class represents a proxy class
generated by this factory, else false.private <T> T getProxyImpl(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy,
java.util.function.Supplier<ProxyAssemblerPlugin> plugin,
java.lang.reflect.InvocationHandler handler)
If a proxy class does not yet exist which meets the given criteria, one is assembled and loaded on the fly.
Implementation Note: if multiple interfaces specify methods with compatible signatures and return types, but different lists of exception types, the first method discovered which has a return type which is assignable from all other, matching methods is used for the dynamic proxy, regardless of the exception list. The order in which methods are checked is indeterminate. Therefore, callers should be careful to specify methods with matching exception lists, if methods with the same name, signature, and compatible return types are specified across interfaces.
T - Type of the proxy class which will be returned.parent - Superclass of the proxy class. If handler is
null, this class is expected to implement the
InvocationHandler interface.proxyParent - Flag indicating that all public and protected parent class methods will be proxied.interfaces - Array of interfaces which must be implemented by the proxy
class.declaredOnly - If true, only methods explicitly declared by the
given interfaces are used; if false, methods
declared by the given interfaces and by any of their ancestor
interfaces are used.doNotProxy - An optional array of Method objects which are not
to be implemented by the dynamically generated proxy. This
option should be used only to represent methods which already
are implemented by the proxy class' superclass.plugin - An optional plugin which can override the assembly of arbitrary methods.handler - Handler to which to dispatch method invocations. If
null, the dynamic proxy instance itself will be
used as the invocation handler.parent and which implements the
methods defined by interfaces.java.lang.IllegalArgumentException - if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types;
if parent is an interface;
if any of the specified interfaces are not
actually interfaces.private java.lang.String makeProxyClassName(java.lang.Class<?> parent,
java.lang.String parentName)
.) character as its
separator, whereas the internal name uses the forward slash
(/).
The package of the superclass becomes the package of the proxy class.
The simple name of the proxy class is $__ProxyN,
where N is an integer unique across all proxy classes generated
by this factory.
parent - Parent class of proxy.parentName - Fully qualified name of parent class.com.goldencode.proxy package name.private java.lang.reflect.Method[] gatherMethods(java.lang.Class<?> parent,
boolean proxyParent,
java.lang.Class<?>[] interfaces,
boolean declaredOnly,
java.lang.reflect.Method[] doNotProxy)
parent - Superclass of the proxy class.proxyParent - Flag indicating that all public and protected parent class methods will be proxied.interfaces - Array of interfaces which must be implemented by the proxy
class.declaredOnly - If true, only methods explicitly declared by the
given interfaces are used; if false, methods
declared by the given interfaces and by any of their ancestor
interfaces are used.doNotProxy - An optional array of Method objects which are not
to be implemented by the dynamically generated proxy. This
option should be used only to represent methods which already
are implemented by the proxy class' superclass.java.lang.IllegalArgumentException - if multiple interfaces specify methods which share a name and
parameter signature, but which have incompatible return types.private java.lang.reflect.Method identifyBestMethod(java.util.Set<java.lang.reflect.Method> methods)
methods - A set of methods which share a name and parameter signature,
but not necessarily the same return type.java.lang.IllegalArgumentException - if multiple methods exist in the set, but none has a return
type that is assignable from all the others.