org.springframework.cglib.proxy

## Class Enhancer

- java.lang.Object
- - org.springframework.cglib.core.AbstractClassGenerator
  - - org.springframework.cglib.proxy.Enhancer

- All Implemented Interfaces:
    org.springframework.cglib.core.ClassGenerator

      public class Enhancer
      extends AbstractClassGenerator

  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.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static interface` | `Enhancer.EnhancerKey` Internal interface, only public due to ClassLoader issues.

    - ### Nested classes/interfaces inherited from class org.springframework.cglib.core.AbstractClassGenerator

      `AbstractClassGenerator.ClassLoaderData, AbstractClassGenerator.Source`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Enhancer()` Create a new `Enhancer`.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `Object` | `create()` Generate a new class if necessary and uses the specified callbacks (if any) to create a new object instance.
    `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.
    `static Object` | `create(Class type, org.springframework.cglib.proxy.Callback callback)` Helper method to create an intercepted object.
    `static Object` | `create(Class superclass, Class[] interfaces, org.springframework.cglib.proxy.Callback callback)` Helper method to create an intercepted object.
    `static Object` | `create(Class superclass, Class[] interfaces, org.springframework.cglib.proxy.CallbackFilter filter, org.springframework.cglib.proxy.Callback[] callbacks)` Helper method to create an intercepted object.
    `Class` | `createClass()` Generate a new class if necessary and return it without creating a new instance.
    `protected void` | `filterConstructors(Class sc, List constructors)` Filter the list of constructors from the superclass.
    `protected Object` | `firstInstance(Class type)` This method should not be called in regular flow.
    `protected Class` | `generate(AbstractClassGenerator.ClassLoaderData data)`
    `void` | `generateClass(ClassVisitor v)`
    `protected ClassLoader` | `getDefaultClassLoader()`
    `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.
    `protected ProtectionDomain` | `getProtectionDomain()` Returns the protection domain to use when defining the class.
    `static boolean` | `isEnhanced(Class type)` Determine if a class was generated using `Enhancer`.
    `protected Object` | `nextInstance(Object instance)`
    `static void` | `registerCallbacks(Class generatedClass, org.springframework.cglib.proxy.Callback[] callbacks)` Call this method to register the `Callback` array to use before creating a new instance of the generated class via reflection.
    `static void` | `registerStaticCallbacks(Class generatedClass, org.springframework.cglib.proxy.Callback[] callbacks)` Similar to `registerCallbacks(java.lang.Class, org.springframework.cglib.proxy.Callback[])`, but suitable for use when multiple threads will be creating instances of the generated class.
    `void` | `setCallback(org.springframework.cglib.proxy.Callback callback)` Set the single `Callback` to use.
    `void` | `setCallbackFilter(org.springframework.cglib.proxy.CallbackFilter filter)` Set the `CallbackFilter` used to map the generated class' methods to a particular callback index.
    `void` | `setCallbacks(org.springframework.cglib.proxy.Callback[] callbacks)` Set the array of callbacks to use.
    `void` | `setCallbackType(Class callbackType)` Set the single type of `Callback` to use.
    `void` | `setCallbackTypes(Class[] callbackTypes)` Set the array of callback types to use.
    `void` | `setInterceptDuringConstruction(boolean interceptDuringConstruction)` Set whether methods called from within the proxy's constructer will be intercepted.
    `void` | `setInterfaces(Class[] interfaces)` Set the interfaces to implement.
    `void` | `setSerialVersionUID(Long sUID)` Insert a static serialVersionUID field into the generated class.
    `void` | `setSuperclass(Class superclass)` Set the class which the generated class will extend.
    `void` | `setUseFactory(boolean useFactory)` Set whether the enhanced object instances should implement the `Factory` interface.
    `protected Object` | `unwrapCachedValue(Object cached)`
    `protected Object` | `wrapCachedClass(Class klass)`

    - ### Methods inherited from class org.springframework.cglib.core.AbstractClassGenerator

      `create, getAttemptLoad, getClassLoader, getClassName, getCurrent, getNamingPolicy, getStrategy, getUseCache, setAttemptLoad, setClassLoader, setContextClass, setNamePrefix, setNamingPolicy, setStrategy, setUseCache`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### Enhancer

          public Enhancer()

      Create a new `Enhancer`. A new `Enhancer` object should be used for each generated object, and should not be shared across threads. To create additional instances of a generated class, use the `Factory` interface.
      See Also:
        `Factory`

  - ### Method Detail

    - #### 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.
      Parameters:
        `superclass` - class to extend or interface to implement
      See Also:
        `setInterfaces(Class[])`

    - #### setInterfaces

          public void setInterfaces(Class[] interfaces)

      Set the interfaces to implement. The `Factory` interface will always be implemented regardless of what is specified here.
      Parameters:
        `interfaces` - array of interfaces to implement, or null
      See Also:
        `Factory`

    - #### setCallbackFilter

          public void setCallbackFilter(org.springframework.cglib.proxy.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.
      Parameters:
        `filter` - the callback filter to use when generating a new class
      See Also:
        `setCallbacks(org.springframework.cglib.proxy.Callback[])`

    - #### setCallback

          public void setCallback(org.springframework.cglib.proxy.Callback callback)

      Set the single `Callback` to use. Ignored if you use `createClass()`.
      Parameters:
        `callback` - the callback to use for all methods
      See Also:
        `setCallbacks(org.springframework.cglib.proxy.Callback[])`

    - #### setCallbacks

          public void setCallbacks(org.springframework.cglib.proxy.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.
      Parameters:
        `callbacks` - the callback array
      See Also:
        `setCallbackFilter(org.springframework.cglib.proxy.CallbackFilter)`, `setCallback(org.springframework.cglib.proxy.Callback)`

    - #### 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.
      Parameters:
        `useFactory` - whether to implement `Factory`; default is `true`

    - #### 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.
      Parameters:
        `interceptDuringConstruction` - whether to intercept methods called from the constructor

    - #### setCallbackType

          public void setCallbackType(Class callbackType)

      Set the single type of `Callback` to use. This may be used instead of `setCallback(org.springframework.cglib.proxy.Callback)` when calling `createClass()`, since it may not be possible to have an array of actual callback instances.
      Parameters:
        `callbackType` - the type of callback to use for all methods
      See Also:
        `setCallbackTypes(java.lang.Class[])`

    - #### setCallbackTypes

          public void setCallbackTypes(Class[] callbackTypes)

      Set the array of callback types to use. This may be used instead of `setCallbacks(org.springframework.cglib.proxy.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.
      Parameters:
        `callbackTypes` - the array of callback types

    - #### 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.
      Returns:
        a new instance

    - #### 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.
      Parameters:
        `argumentTypes` - constructor signature
        `arguments` - compatible wrapped arguments to pass to constructor
      Returns:
        a new instance

    - #### 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.
      See Also:
        `create(Class[], Object[])`

    - #### setSerialVersionUID

          public void setSerialVersionUID(Long sUID)

      Insert a static serialVersionUID field into the generated class.
      Parameters:
        `sUID` - the field value, or null to avoid generating field.

    - #### generate

          protected Class generate(AbstractClassGenerator.ClassLoaderData data)

      Overrides:
        `generate` in class `AbstractClassGenerator`

    - #### getDefaultClassLoader

          protected ClassLoader getDefaultClassLoader()

      Specified by:
        `getDefaultClassLoader` in class `AbstractClassGenerator`

    - #### getProtectionDomain

          protected ProtectionDomain getProtectionDomain()

      Description copied from class: `AbstractClassGenerator`
      Returns the protection domain to use when defining the class.

      Default implementation returns `null` for using a default protection domain. Sub-classes may override to use a more specific protection domain.

      Overrides:
        `getProtectionDomain` in class `AbstractClassGenerator`
      Returns:
        the protection domain (`null` for using a default)

    - #### 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.
      Parameters:
        `superclass` - the class that will be extended, or null
        `interfaces` - the list of interfaces that will be implemented, or null
        `methods` - the list into which to copy the applicable methods

    - #### generateClass

          public void generateClass(ClassVisitor v)
                             throws Exception

      Throws:
        `Exception`

    - #### filterConstructors

          protected void filterConstructors(Class sc,
                                            List constructors)

      Filter the list of constructors from the superclass. The constructors which remain will be included in the generated class. The default implementation is to filter out all private constructors, but subclasses may extend Enhancer to override this behavior.
      Parameters:
        `sc` - the superclass
        `constructors` - the list of all declared constructors from the superclass
      Throws:
        `IllegalArgumentException` - if there are no non-private constructors

    - #### firstInstance

          protected Object firstInstance(Class type)
                                  throws Exception

      This method should not be called in regular flow. Technically speaking `wrapCachedClass(Class)` uses `Enhancer.EnhancerFactoryData` as a cache value, and the latter enables faster instantiation than plain old reflection lookup and invoke. This method is left intact for backward compatibility reasons: just in case it was ever used.
      Specified by:
        `firstInstance` in class `AbstractClassGenerator`
      Parameters:
        `type` - class to instantiate
      Returns:
        newly created proxy instance
      Throws:
        `Exception` - if something goes wrong

    - #### nextInstance

          protected Object nextInstance(Object instance)

      Specified by:
        `nextInstance` in class `AbstractClassGenerator`

    - #### wrapCachedClass

          protected Object wrapCachedClass(Class klass)

      Overrides:
        `wrapCachedClass` in class `AbstractClassGenerator`

    - #### unwrapCachedValue

          protected Object unwrapCachedValue(Object cached)

      Overrides:
        `unwrapCachedValue` in class `AbstractClassGenerator`

    - #### registerCallbacks

          public static void registerCallbacks(Class generatedClass,
                                               org.springframework.cglib.proxy.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(java.lang.Class, org.springframework.cglib.proxy.Callback[])`.

      The registered callbacks are overwritten and subsequently cleared when calling any of the `create` methods (such as `create()`), or any `Factory` `newInstance` method. Otherwise they are not cleared, and you should be careful to set them back to `null` after creating new instances via reflection if memory leakage is a concern.

      Parameters:
        `generatedClass` - a class previously created by `Enhancer`
        `callbacks` - the array of callbacks to use when instances of the generated class are created
      See Also:
        `setUseFactory(boolean)`

    - #### registerStaticCallbacks

          public static void registerStaticCallbacks(Class generatedClass,
                                                     org.springframework.cglib.proxy.Callback[] callbacks)

      Similar to `registerCallbacks(java.lang.Class, org.springframework.cglib.proxy.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.
      Parameters:
        `generatedClass` - a class previously created by `Enhancer`
        `callbacks` - the array of callbacks to use when instances of the generated class are created

    - #### isEnhanced

          public static boolean isEnhanced(Class type)

      Determine if a class was generated using `Enhancer`.
      Parameters:
        `type` - any class
      Returns:
        whether the class was generated using `Enhancer`

    - #### create

          public static Object create(Class type,
                                      org.springframework.cglib.proxy.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.
      Parameters:
        `type` - class to extend or interface to implement
        `callback` - the callback to use for all methods

    - #### create

          public static Object create(Class superclass,
                                      Class[] interfaces,
                                      org.springframework.cglib.proxy.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.
      Parameters:
        `superclass` - class to extend or interface to implement
        `interfaces` - array of interfaces to implement, or null
        `callback` - the callback to use for all methods

    - #### create

          public static Object create(Class superclass,
                                      Class[] interfaces,
                                      org.springframework.cglib.proxy.CallbackFilter filter,
                                      org.springframework.cglib.proxy.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.
      Parameters:
        `superclass` - class to extend or interface to implement
        `interfaces` - array of interfaces to implement, or null
        `filter` - the callback filter to use when generating a new class
        `callbacks` - callback implementations to use for the enhanced object