摘要

  • 别离演示动态代理和动静代理

动态代理

手动代理

interface

public interface Interface_ {    public void do();}

须要被增强的类

public class Object_ implements Interface_{    @Override    public void do() {        System.out.println("do");    }}

代理类

public class Object_Agent implements Interface_{    private Object_ object_;    public Object_Agent(Object_ object_) {        this.object_ = object_;    }    @Override    public  void do() {        System.out.println("enhance");        object_.do();    }        public static void main(String[] args) {        Object_ object_ = new Object_();        Object_Agent agent = new Object_Agent(object_);        agent.do();    }}

AspectJ动态

  • 编写形式和spring aop没有区别
  • Aspectj并不是动静的在运行时生成代理类,而是在编译的时候就植入代码到class文件
  • 因为是动态织入的,所以性能相对来说比拟好

动静代理

  • JDK动静代理是基于接口的形式,代理类和指标类都实现同一个接口。
  • CGLib动静代理是代理类去继承指标类,而后重写其中指标类的办法。

JDK动静代理

接口

public interface Interface_ {    public void do();}

须要被增强的类

public class Object_ implements Interface_{    @Override    public void do() {        System.out.println("do");    }}

处理器实现类

public class InvocationHandlerImpl implements InvocationHandler{    private Object object;    public InvocationHandlerImpl(Object object)    {        this.object = object;    }    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable    {        System.out.println("enhance");        Object object = method.invoke(object, args);        return object;    }}

测试

public class DynamicProxyDemonstration{    public static void main(String[] args)    {        Interface_ object_ = new Object_();        InvocationHandler handler = new InvocationHandlerImpl(object_);        ClassLoader loader = object_.getClass().getClassLoader();        Class[] interfaces = object_.getClass().getInterfaces();        Interface_ object__ = (Interface_) Proxy.newProxyInstance(loader, interfaces, handler);         object__.do();    } }

CGlib动静代理

POM

<dependency>        <groupId>cglib</groupId>        <artifactId>cglib</artifactId>        <version>2.2.2</version></dependency>

须要被增强的类

public class Object_{    public  void do() {        System.out.println("do");    }}

办法拦截器

public class MyMethodInterceptor implements MethodInterceptor{    @Override    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {        System.out.println("enhance");        Object object = proxy.invokeSuper(obj, args);        return object;    }  }

测试

public class CgLibProxy {    public static void main(String[] args) {        //创立Enhancer对象,相似于JDK动静代理的Proxy类,下一步就是设置几个参数        Enhancer enhancer = new Enhancer();        //设置指标类的字节码文件        enhancer.setSuperclass(Object_.class);        //设置回调函数        enhancer.setCallback(new MyMethodInterceptor());        //创立加运行        Object_ proxyObject_ = (Object_)enhancer.create();        proxyObject_.do();           }}

为啥转变被CGlib

个别写代码:

@AutowiredUserService userService;

出错代码:

@AutowiredUserServiceImpl userService;

JDK 动静代理是基于接口的,代理生成的对象只能赋值给接口变量。

而 CGLIB 就不存在这个问题。因为 CGLIB 是通过生成子类来实现的,代理对象无论是赋值给接口还是实现类这两者都是代理对象的父类。

总结

  • Spring5 默认aop实现为CGlib
  • JDK动静代理是基于接口的,CGlib动静代理是基于继承的

参考

[1].CGLib动静代理

[2].java反射和代理

[3].惊人!Spring5 AOP 默认应用Cglib? 从景象到源码深度剖析

本文作者: Both Savage

本文链接: https://bothsavage.github.io/...

版权申明: 本博客所有文章除特地申明外,均采纳 BY-NC-SA 许可协定。转载请注明出处!