Generates dynamic subclasses to enable method interception. This
class started as a substitute for the standard Dynamic Proxy support
included with JDK 1.3, but one that allowed the proxies to extend a
concrete base class, in addition to implementing interfaces. The dynamically
generated subclasses override the non-final methods of the superclass and
have hooks which callback to user-defined interceptor
implementations.
The original and most general callback type is the
MethodInterceptor
, which
in AOP terms enables "around advice"--that is, you can invoke custom code both before
and after the invocation of the "super" method. In addition you can modify the
arguments before calling the super method, or not call it at all.
Although
MethodInterceptor
is generic enough to meet any
interception need, it is often overkill. For simplicity and performance, additional
specialized callback types, such as
LazyLoader
are also available.
Often a single callback will be used per enhanced class, but you can control
which callback is used on a per-method basis with a
CallbackFilter
.
The most common uses of this class are embodied in the static helper methods. For
advanced needs, such as customizing the
ClassLoader
to use, you should create
a new instance of
Enhancer
. Other classes within CGLIB follow a similar pattern.
All enhanced objects implement the
Factory
interface, unless
setUseFactory(boolean)
is
used to explicitly disable this feature. The
Factory
interface provides an API
to change the callbacks of an existing object, as well as a faster and easier way to create
new instances of the same type.
For an almost drop-in replacement for
java.lang.reflect.Proxy
, see the
Proxy
class.
create
public Object create()
Generate a new class if necessary and uses the specified
callbacks (if any) to create a new object instance.
Uses the no-arg constructor of the superclass.
create
public static Object create(Class superclass,
Class[] interfaces,
CallbackFilter filter,
Callback[] callbacks)
Helper method to create an intercepted object.
For finer control over the generated instance, use a new instance of Enhancer
instead of this static method.
interfaces
- array of interfaces to implement, or nullfilter
- the callback filter to use when generating a new classcallbacks
- callback implementations to use for the enhanced object
create
public static Object create(Class superclass,
interfaces[] ,
Callback callback)
Helper method to create an intercepted object.
For finer control over the generated instance, use a new instance of Enhancer
instead of this static method.
callback
- the callback to use for all methods
create
public static Object create(Class type,
Callback callback)
Helper method to create an intercepted object.
For finer control over the generated instance, use a new instance of Enhancer
instead of this static method.
type
- class to extend or interface to implementcallback
- the callback to use for all methods
create
public Object create(Class[] argumentTypes,
Object[] arguments)
Generate a new class if necessary and uses the specified
callbacks (if any) to create a new object instance.
Uses the constructor of the superclass matching the argumentTypes
parameter, with the given arguments.
argumentTypes
- constructor signaturearguments
- compatible wrapped arguments to pass to constructor
createClass
public Class createClass()
Generate a new class if necessary and return it without creating a new instance.
This ignores any callbacks that have been set.
To create a new instance you will have to use reflection, and methods
called during the constructor will not be intercepted. To avoid this problem,
use the multi-arg create
method.
getMethods
public static void getMethods(Class superclass,
Class[] interfaces,
List methods)
Finds all of the methods that will be extended by an
Enhancer-generated class using the specified superclass and
interfaces. This can be useful in building a list of Callback
objects. The methods are added to the end of the given list. Due
to the subclassing nature of the classes generated by Enhancer,
the methods are guaranteed to be non-static, non-final, and
non-private. Each method signature will only occur once, even if
it occurs in multiple classes.
superclass
- the class that will be extended, or nullinterfaces
- the list of interfaces that will be implemented, or nullmethods
- the list into which to copy the applicable methods
isEnhanced
public static boolean isEnhanced(Class type)
Determine if a class was generated using Enhancer
.
- whether the class was generated using
Enhancer
registerCallbacks
public static void registerCallbacks(Class generatedClass,
Callback[] callbacks)
Call this method to register the
Callback
array to use before
creating a new instance of the generated class via reflection. If you are using
an instance of
Enhancer
or the
Factory
interface to create
new instances, this method is unnecessary. Its primary use is for when you want to
cache and reuse a generated class yourself, and the generated class does
not implement the
Factory
interface.
Note that this method only registers the callbacks on the current thread.
If you want to register callbacks for instances created by multiple threads,
use
registerStaticCallbacks(Class,Callback[])
.
The registered callbacks are overwritten and subsequently cleared
when calling any of the
create
methods (such as
create
).
generatedClass
- a class previously created by Enhancer
callbacks
- the array of callbacks to use when instances of the generated
class are created
registerStaticCallbacks
public static void registerStaticCallbacks(Class generatedClass,
Callback[] callbacks)
Similar to
registerCallbacks(Class,Callback[])
, but suitable for use
when multiple threads will be creating instances of the generated class.
The thread-level callbacks will always override the static callbacks.
Static callbacks are never cleared.
generatedClass
- a class previously created by Enhancer
callbacks
- the array of callbacks to use when instances of the generated
class are created
setCallback
public void setCallback(Callback callback)
callback
- the callback to use for all methods
setCallbackFilter
public void setCallbackFilter(CallbackFilter filter)
Set the
CallbackFilter
used to map the generated class' methods
to a particular callback index.
New object instances will always use the same mapping, but may use different
actual callback objects.
filter
- the callback filter to use when generating a new class
setCallbackType
public void setCallbackType(Class callbackType)
callbackType
- the type of callback to use for all methods
setCallbackTypes
public void setCallbackTypes(Class[] callbackTypes)
Set the array of callback types to use.
This may be used instead of
setCallbacks(Callback[])
when calling
createClass()
, since it may not be possible to have
an array of actual callback instances.
You must use a
CallbackFilter
to specify the index into this
array for each method in the proxied class.
callbackTypes
- the array of callback types
setCallbacks
public void setCallbacks(Callback[] callbacks)
Set the array of callbacks to use.
Ignored if you use
createClass()
.
You must use a
CallbackFilter
to specify the index into this
array for each method in the proxied class.
callbacks
- the callback array
setInterceptDuringConstruction
public void setInterceptDuringConstruction(boolean interceptDuringConstruction)
Set whether methods called from within the proxy's constructer
will be intercepted. The default value is true. Unintercepted methods
will call the method of the proxy's base class, if it exists.
interceptDuringConstruction
- whether to intercept methods called from the constructor
setInterfaces
public void setInterfaces(Class[] interfaces)
Set the interfaces to implement. The Factory
interface will
always be implemented regardless of what is specified here.
interfaces
- array of interfaces to implement, or null
setSerialVersionUID
public void setSerialVersionUID(Long sUID)
Insert a static serialVersionUID field into the generated class.
sUID
- the field value, or null to avoid generating field.
setSuperclass
public void setSuperclass(Class superclass)
Set the class which the generated class will extend. As a convenience,
if the supplied superclass is actually an interface, setInterfaces
will be called with the appropriate argument instead.
A non-interface argument must not be declared as final, and must have an
accessible constructor.
superclass
- class to extend or interface to implement
setUseFactory
public void setUseFactory(boolean useFactory)
Set whether the enhanced object instances should implement
the
Factory
interface.
This was added for tools that need for proxies to be more
indistinguishable from their targets. Also, in some cases it may
be necessary to disable the
Factory
interface to
prevent code from changing the underlying callbacks.
useFactory
- whether to implement Factory
; default is true