Java Proxies
JDK Dynamic Proxy
CGLib
Java Reflection
Java Performance

What is the difference between JDK dynamic proxy and CGLib?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In Java, dynamic proxies and CGLIB (Code Generation Library) are two prominent techniques for creating proxy objects. These proxies help developers implement methods like logging, transaction management, and performance monitoring without altering the original codebase. While both serve similar purposes, they differ significantly in their implementation and use cases. Let's explore these differences in detail.

Dynamic Proxies with JDK

Overview

Java Development Kit (JDK) dynamic proxies were introduced with Java 1.3. They operate using interfaces and are inherently part of the Java standard library. The java.lang.reflect.Proxy class and the InvocationHandler interface facilitate their creation and management.

Technical Explanation

  • Interface-Based: JDK dynamic proxies are built around interfaces. This means that the target object must implement one or more interfaces for the proxying mechanism to work.
  • InvocationHandler Interface: When creating a dynamic proxy, you'll implement the InvocationHandler interface, primarily defining the invoke method. This method is called whenever any method on the proxy instance is invoked.
  • Proxy Creation: You use Proxy.newProxyInstance() to create a new proxy instance. This static method requires a class loader, an array of interfaces, and the InvocationHandler implementation.

Example

Here's a simple example demonstrating a dynamic proxy with JDK:

java
1import java.lang.reflect.InvocationHandler;
2import java.lang.reflect.Method;
3import java.lang.reflect.Proxy;
4
5// Define an interface
6interface Service {
7    void perform();
8}
9
10// Real object implementing the interface
11class RealService implements Service {
12    public void perform() {
13        System.out.println("Performing real service operation.");
14    }
15}
16
17// InvocationHandler implementation
18class ServiceInvocationHandler implements InvocationHandler {
19    private final Service target;
20
21    public ServiceInvocationHandler(Service target) {
22        this.target = target;
23    }
24
25    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
26        System.out.println("Before method: " + method.getName());
27        Object result = method.invoke(target, args);
28        System.out.println("After method: " + method.getName());
29        return result;
30    }
31}
32
33// Utilizing the dynamic proxy
34public class ProxyExample {
35    public static void main(String[] args) {
36        Service service = new RealService();
37        Service proxyInstance = (Service) Proxy.newProxyInstance(
38            service.getClass().getClassLoader(),
39            service.getClass().getInterfaces(),
40            new ServiceInvocationHandler(service)
41        );
42
43        proxyInstance.perform();
44    }
45}

CGLIB Proxies

Overview

CGLIB is a third-party library developed by Hibernate for creating proxy classes. Unlike JDK dynamic proxies, CGLIB uses subclassing to generate proxy instances, thus eliminating the requirement for target objects to implement interfaces.

Technical Explanation

  • Subclass-Based: CGLIB proxies work by subclassing the target class. As such, it can proxy classes without interfaces, making it more versatile for objects without explicit contracts defined in interfaces.
  • Method Interceptor: CGLIB utilizes the MethodInterceptor interface, where the intercept method intercepts all method calls on the proxied object.
  • Proxy Creation: Proxies are created using Enhancer class provided by the CGLIB library. You need to set the superclass for the proxy and implement MethodInterceptor.

Example

Here's how to create a proxy using CGLIB:

java
1import net.sf.cglib.proxy.Enhancer;
2import net.sf.cglib.proxy.MethodInterceptor;
3import net.sf.cglib.proxy.MethodProxy;
4
5import java.lang.reflect.Method;
6
7// Real object without an interface
8class RealService {
9    public void perform() {
10        System.out.println("Performing real service operation.");
11    }
12}
13
14// MethodInterceptor implementation
15class ServiceMethodInterceptor implements MethodInterceptor {
16    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
17        System.out.println("Before method: " + method.getName());
18        Object result = proxy.invokeSuper(obj, args);
19        System.out.println("After method: " + method.getName());
20        return result;
21    }
22}
23
24// Utilizing the CGLIB proxy
25public class CglibProxyExample {
26    public static void main(String[] args) {
27        Enhancer enhancer = new Enhancer();
28        enhancer.setSuperclass(RealService.class);
29        enhancer.setCallback(new ServiceMethodInterceptor());
30
31        RealService proxy = (RealService) enhancer.create();
32        proxy.perform();
33    }
34}

Key Differences Between JDK Dynamic Proxies and CGLIB

Here's a summary comparing JDK dynamic proxies and CGLIB:

FeatureJDK Dynamic ProxyCGLIB Proxy
Interface RequirementRequires target to implement an interfaceNo interface requirement processes classes directly
Proxy MechanismInterface-basedSubclass-based
PerformanceTypically faster for objects that implement interfacesSlightly slower due to subclassing
LimitationsCannot proxy concrete classesCannot proxy final classes or final methods
External DependencyPart of standard JDKRequires CGLIB library dependency
Use CaseBest for service-oriented interfacesFlexible for wider use cases without interfaces

Conclusion

Choosing between JDK dynamic proxies and CGLIB depends on your specific requirements. If your classes are interface-based, JDK dynamic proxies provide an elegant and performance-efficient solution. However, if you need to proxy concrete classes without interfaces, CGLIB offers the flexibility required, albeit with some limitations on proxying final classes or methods. Understanding these nuances helps in selecting the right tool for effective proxy implementation in Java applications.


Course illustration
Course illustration

All Rights Reserved.