When working with Java, you may come across the need for dynamic proxy objects to perform interception or extend functionality of existing classes. Two commonly used libraries for creating dynamic proxies in Java are CGLIB and JDK Dynamic Proxy. In this blog post, we will explore the difference between these two approaches and when to choose one over the other.
JDK Dynamic Proxy
JDK Dynamic Proxy is part of the Java core libraries and provides a simple way to create dynamic proxies. It operates by creating proxies based on interfaces, allowing you to intercept method invocations on the proxy object. JDK Dynamic Proxy can be used with any interface-based class, making it a versatile option.
To create a dynamic proxy using JDK Dynamic Proxy, you need to define an interface that the proxy will implement. Then, you can use the java.lang.reflect.Proxy
class to create the proxy object. The proxy object will delegate method invocations to the InvocationHandler
implementation provided.
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface MyInterface {
void doSomething();
}
class MyInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Perform some pre-processing logic before method invocation
Object result = method.invoke(this, args);
// Perform some post-processing logic after method invocation
return result;
}
}
public class Main {
public static void main(String[] args) {
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
Main.class.getClassLoader(),
new Class[] { MyInterface.class },
new MyInvocationHandler()
);
proxy.doSomething();
}
}
CGLIB
CGLIB is a bytecode generation library that allows you to create dynamic proxies without the need for interfaces. Unlike JDK Dynamic Proxy, CGLIB generates subclasses of the target class on-the-fly, with the ability to override its methods and intercept method invocations. This makes CGLIB a powerful option when working with classes that don’t have interface definitions.
To use CGLIB, you need to include the CGLIB library in your project dependencies. Then, you can create a MethodInterceptor
implementation and use the Enhancer
class to create the proxy object.
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class MyInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
// Perform some pre-processing logic before method invocation
Object result = proxy.invokeSuper(obj, args);
// Perform some post-processing logic after method invocation
return result;
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MyClass.class);
enhancer.setCallback(new MyInterceptor());
MyClass proxy = (MyClass) enhancer.create();
proxy.doSomething();
}
}
Choosing Between CGLIB and JDK Dynamic Proxy
In general, JDK Dynamic Proxy is the preferred choice when you have interfaces available and want to create proxy objects based on them. It is lightweight, part of the Java core libraries, and performs well for most use cases.
On the other hand, if you need to create proxies for classes that don’t have interfaces, or if you require more control over the proxying process, CGLIB is a great choice. It allows you to create proxies for classes on-the-fly and provides powerful method interception capabilities.
Both CGLIB and JDK Dynamic Proxy have their own strengths and can be used effectively based on your specific requirements. Choose the one that best suits your needs and enjoy the flexibility and power of dynamic proxies in your Java applications!
#hashtags: #CGLIB #JDKDynamicProxy