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