jdk动态代理生成:
- /**
- * jdk 动态代理生成 代码分析
- * @author quz
- */
- // 需要继承InvocationHandler
- public class Analysis implements InvocationHandler {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- return null;
- }
- }
这里继承的InvocationHandler 里面需要实现一个invoke 方法
Proxy:代理对象
Method:需要实现的方法
Args:传递的参数
- // 需要继承InvocationHandler
- public class Analysis implements InvocationHandler {
- // 注入被代理类
- Object target;
- // 构造器传参
- public Analysis(Object target) {
- this.target = target;
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("method pre running....");
- // 调用目标方法 反射执行
- Object o = method.invoke(target, args);
- System.out.println("method after running....");
- return o;
- }
- // 动态生成代理对象
- public <T> T getProxy() {
- return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
- }
- }
这里需要传递一个被代理类,使用构造函数进行传递。也就是target需要被构造函数传递,需要让Proxy 去代理生成被代理类,newProxyInstance() 有三个参数
ClassLoader classloader // 获取到类加载器
Class<?> classInfo // 通过反射获取类的信息
this // 当前类,为什么要传递当前类?因为需要在接下来的动态代理生成中,将类的invoke 方法 进行注入. 接下来源码中会有体现.
Proxy 具体如何生成的代理实现?
首先Proxy通过反射获取传递的classInfo,可以拼接成一个类的具体实现,然后在拼接的类实现中注入传递的this,即InvocationHandler 通过传递的InvocationHandler 获取内部的invoke方法,通过classInfo 反射机制 传递method 以及需要被代理的类 注入进去,这样就实现了动态代理
cglib动态代理生成:
- public class CglibMethodInterceptor implements MethodInterceptor {
- /**
- * cglib 动态代理实现源码分析
- * @author quz
- */
- public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {
- System.out.println(">>>cglib动态代理执行开始<<");
- Object result = proxy.invokeSuper(o, args);
- System.out.println(">>>cglib动态代理执行结束<<");
- return result;
- }
- }
通过 proxy 生成代理对象 来实现调用方法
通过debug 查看 参数 o 指的是通过字节码生成的代理对象 method 也就是被代理类的方法 args是被代理类方法的参数
- public Object invokeSuper(Object obj, Object[] args) throws Throwable {
- try {
- this.init();
- MethodProxy.FastClassInfo fci = this.fastClassInfo;
- return fci.f2.invoke(fci.i2, obj, args);
- } catch (InvocationTargetException var4) {
- throw var4.getTargetException();
- }
- }
调用InvokeSuper 方法
This.init 初始化参数
通过init 方法调用后 生成了f1 f2 i1 i2
其中f1 指的是被代理类的对象 f2 指的是代理类对象 i1 指的是被代理类的实现的方法通过索引计算得出的值,i2 指的是代理类实现的方法通过索引计算得出的值。通过传递值的形式,将方法索引传递,得出需要执行的方法是什么,由此不同于jdk动态代理实现,无需反射技术通过索引机制快速调用方法,这也是性能优于jdk动态代理机制的原因。