CGLIB dynamic proxy and JDK dynamic proxy
This article is from the Huawei cloud community “learn about the JDK dynamic proxy and CGLIB dynamic proxy” by Code.
What’s the difference between the two
Jdk dynamic proxy: Use the interceptor (must implement the InvocationHandler interface) and reflection mechanism to generate a proxy interface anonymous class, before calling the specific method to call the InvokeHandler to handle
2, Cglib dynamic proxy: using the ASM framework, load the class file generated by the proxy object class, and modify its bytecode generation subclass to proxy
So:
If you want to implement JDK dynamic proxies, the proxy class must implement the interface, otherwise it cannot be used;
If you want to use a CGlib dynamic proxy, the proxy class cannot use final modifier classes and methods;
There are: In jdk6 has, jdk7, jdk8 gradually the JDK dynamic proxy after optimization, the call number is less, the JDK efficiency is higher than the additional agency efficiency, only when a large number of calls, jdk6 has and jdk7 than additional agent efficiency is lower, but by jdk8, The JDK agent is more efficient than the CGLIB agent.
How to implement
JDK dynamic proxy
UserService interface
public interface UserService {
void addUser();
void updateUser(String str);
}
Copy the code
UserServiceImpl implementation class
Public class UserServiceImpl implements UserService {@override public void addUser() {system.out.println (" addUser "); } @override public void updateUser(String STR) {system.out.println (" updateUser "+ STR); }}Copy the code
The UserProxy proxy class implements the InvocationHandler interface to override the Invoke method
public class UserProxy implements InvocationHandler {
private Object target;
public UserProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = method.invoke(target, args);
System.out.println("记录日志");
return res;
}
}
Copy the code
The test test class
public class test { public static void main(String[] args) { UserServiceImpl impl = new UserServiceImpl(); UserProxy userProxy = new UserProxy(impl); UserService userService = (UserService) Proxy.newProxyInstance(impl.getClass().getClassLoader(),impl.getClass().getInterfaces(),userProxy); userService.addUser(); Userservice.updateuser (" : I am a shrimp "); }}Copy the code
Visibility is enhanced to print out logging
CGlib dynamic proxy
Unlike JDK dynamic proxies, CGlib requires importing Jar packages, so I used SpringBoot to import the dependencies directly
<dependency> <groupId>cglib</ artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>Copy the code
UserServiceImpl Proxied class
Public class UserServiceImpl {public void addUser() {system.out.println (" add a user "); } public void deleteUser() {system.out.println (" deleteUser "); }}Copy the code
UserServiceCGlib agent
public class UserServiceCGlib implements MethodInterceptor { private Object target; public UserServiceCGlib() { } public UserServiceCGlib(Object target) { this.target = target; } public Object getProxyInstance() {//1. Create a utility class Enhancer Enhancer = new Enhancer(); SetSuperclass (target.getClass())); //3. Set the callback function enhancer.setCallback(this); Return enhancer. Create (); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy MethodProxy) throws Throwable {system.out.println (" enhancement start ~~~"); Object result = methodProxy.invokeSuper(o, objects); System.out.println(" enhanced end ~~~"); return result; }}Copy the code
The test test class
public class test { public static void main(String[] args) { UserServiceCGlib serviceCGlib = new UserServiceCGlib(new UserServiceImpl()); UserServiceImpl userService = (UserServiceImpl)serviceCGlib.getProxyInstance(); userService.addUser(); System.out.println(); userService.deleteUser(); }}Copy the code
Visibility is enhanced to print out logging
Usage scenarios
Here I believe that you have basically mastered the difference and implementation of JDK dynamic proxy and CGlib dynamic proxy
However, in the interview process, in addition to the above points, you also need to answer how they are used, which is actually a plus
So, what are the usage scenarios of these two dynamic proxies??
Spring AOP
Here is how Spring AOP creates a proxy
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<? > targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } / / if the if (targetClass isInterface () | | Proxy. IsProxyClass (targetClass)) {return new JdkDynamicAopProxy (config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); }}Copy the code
If the target object implements the interface, the JDK’s dynamic proxy is used by default
If the target object implements the interface, you can force the use of CGLIB3. If the target object does not implement the interface, you must use the CGLIB library. Spring will automatically convert the JDK dynamic proxy to CGLIB
If you want to force CGLIB to implement AOP, you need to configure spring.aop.proxy-target-class=true or @enableAspectJAutoProxy (proxyTargetClass= true)
Click to follow, the first time to learn about Huawei cloud fresh technology ~