Code generation library for creating dynamic proxies, bean utilities, and fast reflection alternatives with bundled dependencies
—
Core proxy generation functionality for creating enhanced classes with method interception, callback support, and dynamic interface implementation. This is the heart of CGLib's dynamic proxy capabilities.
The primary class for creating enhanced/proxied subclasses with method interception capabilities.
/**
* Primary class for creating enhanced/proxied subclasses
*/
public class Enhancer {
// Static factory methods for simple use cases
public static Object create(Class type, Callback callback);
public static Object create(Class superclass, Class[] interfaces, Callback callback);
public static Object create(Class superclass, Class[] interfaces,
CallbackFilter filter, Callback[] callbacks);
// Instance configuration methods
public void setSuperclass(Class superclass);
public void setInterfaces(Class[] interfaces);
public void setCallback(Callback callback);
public void setCallbacks(Callback[] callbacks);
public void setCallbackFilter(CallbackFilter filter);
public void setUseFactory(boolean useFactory);
public void setUseCache(boolean useCache);
// Generation methods
public Object create();
public Object create(Class[] argumentTypes, Object[] arguments);
public Class createClass();
// Utility methods
public static void getMethods(Class superclass, Class[] interfaces, List methods);
public static void registerCallbacks(Class generatedClass, Callback[] callbacks);
public static void registerStaticCallbacks(Class generatedClass, Callback[] callbacks);
}Usage Examples:
// Simple method interception
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyService.class);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
long start = System.currentTimeMillis();
try {
return proxy.invokeSuper(obj, args);
} finally {
System.out.println(method.getName() + " took " + (System.currentTimeMillis() - start) + "ms");
}
}
});
MyService proxy = (MyService) enhancer.create();
// Multiple interfaces with constructor arguments
enhancer = new Enhancer();
enhancer.setSuperclass(DatabaseService.class);
enhancer.setInterfaces(new Class[]{Serializable.class, Auditable.class});
enhancer.setCallback(myInterceptor);
DatabaseService service = (DatabaseService) enhancer.create(
new Class[]{String.class},
new Object[]{"jdbc:mysql://localhost/db"}
);
// Multiple callbacks with filter
enhancer = new Enhancer();
enhancer.setSuperclass(BusinessObject.class);
enhancer.setCallbacks(new Callback[]{
methodInterceptor, // index 0
NoOp.INSTANCE, // index 1
fixedValue // index 2
});
enhancer.setCallbackFilter(new CallbackFilter() {
public int accept(Method method) {
if (method.getName().startsWith("get")) return 1; // NoOp
if (method.getName().equals("toString")) return 2; // FixedValue
return 0; // MethodInterceptor
}
});
BusinessObject obj = (BusinessObject) enhancer.create();Intercepts method calls with full control over invocation.
/**
* Intercepts method calls with full control over invocation
*/
public interface MethodInterceptor extends Callback {
/**
* Intercept a method call
* @param obj The enhanced object
* @param method The intercepted Method
* @param args Method arguments
* @param proxy MethodProxy for invoking super method
* @return Method return value
* @throws Throwable Any exception
*/
Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable;
}Returns a fixed value for all intercepted methods.
/**
* Returns a fixed value for all intercepted methods
*/
public interface FixedValue extends Callback {
/**
* Return the fixed value
* @return The value to return for all method calls
* @throws Exception Any exception
*/
Object loadObject() throws Exception;
}Loads a delegate object on first access, then delegates all calls to it.
/**
* Loads a delegate object on first access, then delegates all calls to it
*/
public interface LazyLoader extends Callback {
/**
* Load the delegate object (called only once)
* @return The delegate object
* @throws Exception Any exception
*/
Object loadObject() throws Exception;
}Loads a delegate object for each method call.
/**
* Loads a delegate object for each method call
*/
public interface Dispatcher extends Callback {
/**
* Load the delegate object (called for every method invocation)
* @return The delegate object
* @throws Exception Any exception
*/
Object loadObject() throws Exception;
}Like Dispatcher but provides reference to the proxy object.
/**
* Like Dispatcher but provides reference to the proxy object
*/
public interface ProxyRefDispatcher extends Callback {
/**
* Load the delegate object with access to the proxy
* @param proxy The proxy object
* @return The delegate object
* @throws Exception Any exception
*/
Object loadObject(Object proxy) throws Exception;
}No-operation callback that allows method calls to proceed normally.
/**
* No-operation callback - methods proceed normally
*/
public interface NoOp extends Callback {
// Marker interface - no methods
NoOp INSTANCE = new NoOp() {};
}JDK-compatible invocation handler for interface proxies.
/**
* JDK-compatible invocation handler for interface proxies
*/
public interface InvocationHandler extends Callback {
/**
* Invoke a method on the proxy
* @param proxy The proxy object
* @param method The method being invoked
* @param args Method arguments
* @return Method return value
* @throws Throwable Any exception
*/
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}Determines which callback to use for each method.
/**
* Determines which callback to use for each method
*/
public interface CallbackFilter {
/**
* Choose callback index for a method
* @param method The method being intercepted
* @return Index of callback to use
*/
int accept(Method method);
}Provides faster method invocation alternative to reflection.
/**
* Faster method invocation alternative to reflection
*/
public class MethodProxy {
/**
* Create a MethodProxy
* @param c1 The enhanced class
* @param c2 The original class
* @param desc Method descriptor
* @param name1 Generated method name
* @param name2 Super method name
* @return MethodProxy instance
*/
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2);
/**
* Invoke the original method on the object
* @param obj Target object
* @param args Method arguments
* @return Method return value
* @throws Throwable Any exception
*/
public Object invoke(Object obj, Object[] args) throws Throwable;
/**
* Invoke the super method (recommended for interceptors)
* @param obj Enhanced object
* @param args Method arguments
* @return Method return value
* @throws Throwable Any exception
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable;
/**
* Get method signature
* @return Method signature
*/
public Signature getSignature();
/**
* Get super method name
* @return Super method name
*/
public String getSuperName();
/**
* Get super method index
* @return Super method index
*/
public int getSuperIndex();
}Interface implemented by enhanced objects for callback management.
/**
* Interface for callback management on enhanced objects
*/
public interface Factory {
/**
* Create new instance with single callback
* @param callback The callback to use
* @return New enhanced instance
*/
Object newInstance(Callback callback);
/**
* Create new instance with multiple callbacks
* @param callbacks Array of callbacks
* @return New enhanced instance
*/
Object newInstance(Callback[] callbacks);
/**
* Create new instance with constructor arguments and callbacks
* @param types Constructor parameter types
* @param args Constructor arguments
* @param callbacks Array of callbacks
* @return New enhanced instance
*/
Object newInstance(Class[] types, Object[] args, Callback[] callbacks);
/**
* Get callback by index
* @param index Callback index
* @return The callback
*/
Callback getCallback(int index);
/**
* Set callback by index
* @param index Callback index
* @param callback The callback to set
*/
void setCallback(int index, Callback callback);
/**
* Set all callbacks
* @param callbacks Array of callbacks
*/
void setCallbacks(Callback[] callbacks);
/**
* Get all callbacks
* @return Array of callbacks
*/
Callback[] getCallbacks();
}Creates objects that implement multiple interfaces by delegating to different objects.
/**
* Creates objects implementing multiple interfaces via delegation
*/
public abstract class Mixin {
// Style constants
public static final int STYLE_INTERFACES = 0;
public static final int STYLE_BEANS = 1;
public static final int STYLE_EVERYTHING = 2;
/**
* Create mixin from delegate objects
* @param delegates Array of delegate objects
* @return Mixin instance
*/
public static Mixin create(Object[] delegates);
/**
* Create mixin with specific interfaces
* @param interfaces Interfaces to implement
* @param delegates Delegate objects
* @return Mixin instance
*/
public static Mixin create(Class[] interfaces, Object[] delegates);
/**
* Create new mixin instance with different delegates
* @param delegates New delegate objects
* @return New mixin instance
*/
public abstract Mixin newInstance(Object[] delegates);
}Usage Example:
// Create objects implementing multiple interfaces
interface Readable { String read(); }
interface Writable { void write(String data); }
class Reader implements Readable {
public String read() { return "data"; }
}
class Writer implements Writable {
public void write(String data) { System.out.println(data); }
}
// Create mixin implementing both interfaces
Mixin mixin = Mixin.create(new Object[]{new Reader(), new Writer()});
Object combined = mixin.newInstance(new Object[]{new Reader(), new Writer()});
// Use as either interface
Readable readable = (Readable) combined;
Writable writable = (Writable) combined;
readable.read();
writable.write("hello");Drop-in replacement for JDK dynamic proxies with additional features.
/**
* Drop-in replacement for JDK dynamic proxies
*/
public class Proxy {
/**
* Get proxy class for interfaces
* @param loader ClassLoader to use
* @param interfaces Interfaces to implement
* @return Proxy class
*/
public static Class getProxyClass(ClassLoader loader, Class[] interfaces);
/**
* Create proxy instance
* @param loader ClassLoader to use
* @param interfaces Interfaces to implement
* @param h InvocationHandler
* @return Proxy instance
*/
public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h);
/**
* Check if class is a proxy class
* @param cl Class to check
* @return true if proxy class
*/
public static boolean isProxyClass(Class cl);
/**
* Get invocation handler from proxy
* @param proxy Proxy object
* @return InvocationHandler
*/
public static InvocationHandler getInvocationHandler(Object proxy);
}Abstract utility class for managing multiple callbacks.
/**
* Abstract utility for managing multiple callbacks
*/
public abstract class CallbackHelper {
/**
* Constructor
* @param superclass Superclass for enhanced objects
* @param interfaces Interfaces to implement
*/
public CallbackHelper(Class superclass, Class[] interfaces);
/**
* Get callback for a specific method (implement this)
* @param method The method
* @return Callback for the method
*/
protected abstract Object getCallback(Method method);
/**
* Get all callbacks
* @return Array of callbacks
*/
public Callback[] getCallbacks();
/**
* Get callback filter
* @return CallbackFilter instance
*/
public CallbackFilter getFilter();
}Creates new interfaces at runtime.
/**
* Creates new interfaces at runtime
*/
public class InterfaceMaker {
/**
* Add method signature to interface
* @param signature Method signature
* @param exceptions Exception types
*/
public void add(Signature signature, Type[] exceptions);
/**
* Add method to interface
* @param method Method to add
*/
public void add(Method method);
/**
* Add all methods from a class
* @param clazz Class to copy methods from
*/
public void add(Class clazz);
/**
* Create the interface
* @return Interface class
*/
public Class create();
}/**
* Exception for undeclared checked exceptions
*/
public class UndeclaredThrowableException extends RuntimeException {
/**
* Constructor
* @param t The wrapped exception
*/
public UndeclaredThrowableException(Throwable t);
/**
* Get the wrapped exception
* @return The undeclared throwable
*/
public Throwable getUndeclaredThrowable();
}Install with Tessl CLI
npx tessl i tessl/maven-cglib--cglib-nodep