java反射,JDK代理,CGLIB代理的区别

区别:

JDK代理: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

CGKIB: cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

代码实现:

public interface UserManager {  
    public void addUser(String id, String password);  
    public void delUser(String id);  
} 
public class UserManagerImpl implements UserManager {  
  
    public void addUser(String id, String password) {  
        System.out.println("调用了UserManagerImpl.addUser()方法! ");  
  
    }  
  
    public void delUser(String id) {  
        System.out.println("调用了UserManagerImpl.delUser()方法! ");  
  
    }  
} 

jdk动态代理:

import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
/** 
 * JDK动态代理类:
 */  
public class JDKProxy implements InvocationHandler {
  
    private Object targetObject; // 需要代理的目标对象  
  
    public Object newProxy(Object targetObject) { // 将目标对象传入进行代理  
        this.targetObject = targetObject;   
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
                targetObject.getClass().getInterfaces(), this); // 返回代理对象  
    }  
  
    public Object invoke(Object proxy, Method method, Object[] args) // invoke方法  
            throws Throwable {  
        return method.invoke(targetObject, args);
    }  
}  

CGLibProxy动态代理类:

import java.lang.reflect.Method;  
import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
  
/** 
 * CGLibProxy动态代理类的实例:
 */  
public class CGLibProxy implements MethodInterceptor {  
  
    private Object targetObject; // CGLib需要代理的目标对象  
  
    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; // 返回代理对象  
    }  
  
    public Object intercept(Object proxy, Method method, Object[] args,  
            MethodProxy methodProxy) throws Throwable {  
        Object obj = null;  
        if ("addUser".equals(method.getName())) { // 过滤方法  
            checkPopedom(); // 检查权限  
        }  
        obj = method.invoke(targetObject, args);  
        return obj;  
    }  
  
    private void checkPopedom() {  
        System.out.println(".:检查权限  checkPopedom()!");  
    }  
}  

测试类:

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");
    }  
} 

运行结果:

-----------CGLibProxy-------------
.:检查权限  checkPopedom()!
.: 调用了UserManagerImpl.addUser()方法! 
-----------JDKProxy-------------
.: 调用了UserManagerImpl.addUser()方法! 

参考地址:https://blog.csdn.net/aa292016616/article/details/112183182

posted @ 2021-02-28 20:45  dimlt6  阅读(239)  评论(0编辑  收藏  举报