A Brief discussion on the differences between JDK and CGLIB two agents in Spring

  • 2020-06-19 10:13:24
  • OfStack

1. Difference in principle:

Java dynamic proxy is an anonymous class that implements the proxy interface by using the reflection mechanism and calls InvokeHandler to process it before invoking specific methods.

The cglib dynamic proxy USES the asm open source package to load the class file of the proxy object class and process it by modifying its bytecode subclasses.

1. If the target object implements the interface, AOP will be implemented by dynamic proxy of JDK by default

2. If the target object implements the interface, you can force CGLIB to implement AOP

3. If the target object does not implement the interface, the CGLIB library must be adopted. spring will automatically convert between JDK dynamic proxy and CGLIB

How do I enforce AOP with CGLIB?

(1) Add CGLIB library, SPRING_HOME/cglib/.jar

(2) Add in spring configuration file < aop:aspectj-autoproxy proxy-target-class="true"/ >

What is the difference between JDK dynamic proxy and CGLIB bytecode generation?

(1) JDK dynamic proxy can only generate proxy for the class that implements the interface, but not for the class

(2) CGLIB is a proxy implementation for classes. It mainly generates a subclass of the specified class and overrides the methods therein

This class or method is best not declared as final because it is inherited

2. Code implementation


package com.fy.spring.proxy;    
public interface UserManager {  
  public void addUser(String id, String password);  
  public void delUser(String id);  
}  

package com.fy.spring.proxy;  
  public class UserManagerImpl implements UserManager {  
  
  public void addUser(String id, String password) {  
    System.out.println(".:  Off with the UserManagerImpl.addUser() Methods!  ");  
  
  }  
  
  public void delUser(String id) {  
    System.out.println(".:  Off with the UserManagerImpl.delUser() Methods!  ");  
  
  }  
}  

JDK Dynamic proxy class


package com.fy.spring.proxy;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
/**  
 *  
 * JDK Dynamic proxy class   
 *  
 *  
 */ 
public class JDKProxy implements InvocationHandler {  
  
  private Object targetObject;// The target object for which the proxy is required   
  
  public Object newProxy(Object targetObject) {// Pass the target object into the proxy   
    this.targetObject = targetObject;   
    return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
        targetObject.getClass().getInterfaces(), this);// Return the proxy object   
  }  
  
  public Object invoke(Object proxy, Method method, Object[] args)//invoke methods   
      throws Throwable {  
    checkPopedom();//1 Normally the function that we do the logical processing for example here is the mock check permission   
    Object ret = null;   //  Sets the return value of the method   
    ret = method.invoke(targetObject, args);    // call invoke Method, ret Stores the return value of the method   
    return ret;  
  }  
  
  private void checkPopedom() {// An example that simulates checking permissions   
    System.out.println(".: Check the permissions  checkPopedom()!");  
  }  
}  

CGLibProxy Dynamic proxy class


package com.fy.spring.proxy;    
import java.lang.reflect.Method;  
  
import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
  
/**  
 * CGLibProxy An instance of a dynamic proxy class   
 *   
 *  
 */ public class CGLibProxy implements MethodInterceptor {  
  
  private Object targetObject;// CGLib The target object for which the proxy is required   
  
  public Object createProxyObject(Object obj) {  
    this.targetObject = obj;  
    Enhancer enhancer = new Enhancer();  
    enhancer.setSuperclass(obj.getClass());  
    enhancer.setCallback(this);  
    Object proxyObj = enhancer.create();  
    return proxyObj;//  Return the proxy object   
  }  
  
  public Object intercept(Object proxy, Method method, Object[] args,  
      MethodProxy methodProxy) throws Throwable {  
    Object obj = null;  
    if ("addUser".equals(method.getName())) {//  Filtering methods   
      checkPopedom();//  Check the permissions   
    }  
    obj = method.invoke(targetObject, args);  
    return obj;  
  }  
  
  private void checkPopedom() {  
    System.out.println(".: Check the permissions  checkPopedom()!");  
  }  
}  

The test class:


public class Client {  
  
  public static void main(String[] args) {  
  
    UserManager userManager = (UserManager) new CGLibProxy()  
        .createProxyObject(new UserManagerImpl());  
    System.out.println("-----------CGLibProxy-------------");  
    userManager.addUser("tom", "root");  
    System.out.println("-----------JDKProxy-------------");  
    JDKProxy jdkPrpxy = new JDKProxy();  
    UserManager userManagerJDK = (UserManager) jdkPrpxy  
        .newProxy(new UserManagerImpl());  
    userManagerJDK.addUser("tom", "root");  
  }  
  
}  

Operation results:

-----------CGLibProxy-------------
Check permission checkPopedom()!
UserManagerImpl. addUser() method is used!
-----------JDKProxy-------------
Check permission checkPopedom()!
The UserManagerImpl. addUser() method is used!

The JDK agent is a third party library that does not need to be represented, but can be represented only if the JDK environment is required, and it has several requirements

Implement InvocationHandler Generate proxy objects using ES104en.newProxyInstance The object being represented must implement the interface

CGLib must rely on CGLib's class library, but it requires a class to implement any interface proxy that generates a subclass of the specified class, overrides the methods, and is a proxy that is inherited but recommended for interface programming environments

The interceptor in Hibernate is implemented with CGLib as the relevant agent in Hibernate executes in consideration of the condition that no other interface is required.

Hope this article is helpful to you, JDK and CGLIB in the two agents of the difference between JDK and CGLIB to give you a brief introduction of the content here. Hope you continue to pay attention to our website! Stay tuned to learn more about java.


Related articles: