The differences and choices of CGLIB and JDK dynamic proxy
CGLib and JDK dynamic proxy are two common ways to realize dynamic proxy in Java.When choosing to use, we need to understand their differences and applicable scenarios.
1. Principles and concepts of CGLIB and JDK dynamic proxy:
-JDK dynamic proxy is achieved through the reflection mechanism of Java.It requires an interface by the proxy class and is used to intercept and process it through the InvoCationHandler interface.
-CGLIB dynamic proxy is achieved by inheriting the agent class and rewriting its method.It does not require an interface to be implemented by the proxy class, and can directly proxy the class.
2. Features of CGLIB and JDK dynamic proxy:
-JDK dynamic proxy can only proxy the class of the interface, and the proxy cannot be performed directly for classes without the interface.CGLIB can proxy any class, including classes that have not implemented interfaces.
-JDK dynamic proxy needs to consume a certain time when generating proxy classes, while CGLIB needs more time to generate proxy classes.Therefore, in the scenario of high performance requirements, the JDK dynamic agent may be more suitable.
3. Selection of CGLIB and JDK dynamic proxy:
-If the class of the agent has achieved the interface, the JDK dynamic proxy is given priority.Its use is simpler and does not require extra dependence.
-If the class of the agent does not implement the interface, or you need to proxy the method of the class, you can only choose the CGLIB dynamic proxy.
Here are examples of using JDK dynamic agent and CGLIB dynamic proxy:
JDK dynamic proxy example:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface UserService {
void save();
}
class UserServiceImpl implements UserService {
public void save() {
System.out.println("Save user");
}
}
class LogHandler implements InvocationHandler {
private Object target;
public LogHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
LogHandler logHandler = new LogHandler(userService);
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
logHandler
);
proxy.save();
}
}
CGLIB dynamic proxy example:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class UserService {
public void save() {
System.out.println("Save user");
}
}
class LogInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("After method: " + method.getName());
return result;
}
}
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new LogInterceptor());
UserService userService = (UserService) enhancer.create();
userService.save();
}
}
Through the above code example, we can clearly see the methods and effects of the two dynamic agency methods.According to actual needs and scenes, choose the appropriate dynamic agency method to achieve our agency logic.