JDK 动静代理的实现原理
1、依据传入的类的接口和 InvocationHandler 为接口创立代理类的字节码文件。通过反射创立 method。method 就是接口外面的办法,通过 method 就能够调用实现类重写的办法。
2、应用 ClassLoader 将字节码文件加载到 JVM(定义了一个类,相似于 $Proxy0、$Proxy1 之类的)
3、通过反创立代理类实例对象
4、当调用代理对象办法时,就会进入到 InvocationHandler 的 invoke 办法中,这里就是用户编写的代理逻辑。通过 method.invoke 调用被代理对象的实现逻辑。
通过反射生成 method,而后定义一个 ProxyX 的类,而后反射实例化这个类生成代理对象。代理对象的办法都会进入 InvocationHandler 的 invoke 办法
ps:jdk 代理只能代理接口外面实现的类以及 equals、hashCode、toString 办法。
jdk 代理不反对对实现类的代理,只反对接口的代理,因为生成的类曾经继承了 Proxy,java 不能多继承。
https://blog.csdn.net/mhmyqn/…
cglib 的实现代理的逻辑。
1、首先咱们通过 Enhancer 实例设置被代理类,
2、而后设置该代理类的回调,也就是在拜访代理类办法的时候会首先转向该回调,
3、在回调中咱们调用 invokeSuper 办法以 fastclass 这种非反射机制疾速的调用到代理类中的办法,其中代理类中办法又调用原类型的对应办法。
总结一下 JDK 动静代理和 Gglib 动静代理的区别:
1.JDK 动静代理是实现了被代理对象的接口,Cglib 是继承了被代理对象。
2.JDK 和 Cglib 都是在运行期生成字节码,JDK 是间接写 Class 字节码,Cglib 应用 ASM 框架写 Class 字节码,Cglib 代理实现更简单,生成代理类比 JDK 效率低。
3.JDK 调用代理办法,是通过反射机制调用,Cglib 是通过 FastClass 机制间接调用办法,Cglib 执行效率更高。
https://www.cnblogs.com/monke…
通过 Enhancer 能够生成代理类,传入 CallBack 使代码执行时进入 CallBack 代码中,从而执行用户自定义代码;
用户自定义代码能够决定应用指标类调用还是代理类调用
指标类应用 $$FastClass1 进行调用
代理类应用 $$FastClass2 进行调用
$$FastClass 都在调用时触发生成
$$FastClass 为动静生成类,通过 index 与办法签名一一映射产生 switch case 语句来进步调用效率
代理类是通过继承形式实现,不能对 final 类和办法应用 CGLIB 代理。
因而 CGLB 代理调用效率高,然而生成效率慢,至多 3 个文件,1 个代理类,2 个 FastClass 类。所有生成的类都会加载到 JVM 堆中。
package proxy;
public class BigCar implements Car{
@Override
public void start() {System.out.println("big car start");
}
public void start(int a) {System.out.println("big car start");
}
}
package proxy;
public interface Car {void start();
}
package proxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibInvocationHandler implements MethodInterceptor {
Object target;
public Object getTarget() {return target;}
public void setTarget(Object target) {this.target = target;}
/**
调用过程:代理对象调用 this. 被代理的办法
-> 调用拦截器 intercept
->methodProxy.invokeSuper
->CGLIB$setPerson$0
-> 被代理对象 setPerson 办法
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("cglib proxy start");
// o 是代理对象,methodProxy.invoke 会调用 o 的办法,而后再进入 intercept 办法会造成死循环
Object result = methodProxy.invokeSuper(o, objects);
// 原生 cglib 能够实现外部办法代理,// spring 的 cglib 实现的 aop 不能切到外部调用的办法,除非特意设置
// spring aop 的写法
// spring 会保留实在对象的 bean。// Object result = methodProxy.invoke(target, objects);
System.out.println("cglib proxy end");
return result;
}
}
package proxy;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
public class CglibProxyFactory {public static Object createProxy(Class c,Callback callback){Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(c);
enhancer.setCallback(callback);
return enhancer.create();}
}
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class JdkProxyFactory {public static Object getJDKProxy(Object targetObject, InvocationHandler handler) {
// JDK 动静代理只能针对实现了接口的类进行代理,newProxyInstance 函数所需参数就可看出
// 依据接口类
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
handler);
}
}
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//JDK 动静代理实现 InvocationHandler 接口
public class JdkProxyInvocationHandler implements InvocationHandler {
private Object target;// 须要代理的指标对象
public JdkProxyInvocationHandler(Object target) {this.target = target;}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("JDK 动静代理,监听开始!");
System.out.println(proxy.getClass()+"111");
Object result = method.invoke(target, args);
System.out.println("JDK 动静代理,监听完结!");
return result;
}
}
package proxy;
import net.sf.cglib.core.DebuggingClassWriter;
import java.lang.reflect.Method;
public class Test {public static void main(String[] args) {UserManager target = new UserManagerImpl();
// JdkProxyInvocationHandler handler = new JdkProxyInvocationHandler(target);
// UserManager userManager = (UserManager) JdkProxyFactory.getJDKProxy(target, handler);
// userManager.addUser("1", "1");
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Users\\YEZHENGWU839\\Desktop\\xiaoxi");
CglibInvocationHandler handler1 = new CglibInvocationHandler();
handler1.setTarget(target);
UserManager userManager2 = (UserManager) CglibProxyFactory.createProxy(target.getClass(), handler1);
userManager2.addUser("2","@");
System.out.println(userManager2.getClass().getName());
}
}
package proxy;
public interface UserManager {
// 新增用户形象办法
void addUser(String userName, String password);
// 删除用户形象办法
void delUser(String userName);
default void find(){System.out.println("super interface find");
}
}
package proxy;
// 用户治理实现类, 实现用户治理接口
public class UserManagerImpl implements UserManager {
// 重写新增用户办法
@Override
public void addUser(String userName, String password) {System.out.println("调用了新增的办法!");
System.out.println("传入参数为 userName:" + userName + "password:" + password);
delUser("111");
}
// 重写删除用户办法
@Override
public void delUser(String userName) {System.out.println("调用了删除的办法!");
System.out.println("传入参数为 userName:" + userName);
}
// 不是接口的类 没方法代理
public void show() {System.out.println("this impl method not super method");
}
}