Spring5参考指南:AOP代理

AOP代理

一般来讲Spring AOP有两种代理方式,一种默认的JDK代理,只能代理接口,一种是CGLIB代理,能够代理具体的类对象。java

SpringAOP默认为对AOP代理使用标准的JDK动态代理。若是业务对象不实现接口,则使用CGLIB。git

若是使用CGLIB,要注意对于CGLIB,不能advice final方法,由于它们不能在运行时生成的子类中被重写。github

因为Spring的AOP框架基于代理的特性,根据定义,目标对象内的方法调用不会被拦截。对于JDK代理,只能截获对代理的公共接口方法调用。使用cglib,能够截获代理上的公共和受保护的方法调用(若是须要,甚至能够截获包可见的方法)。spring

若是须要拦截在目标类内的方法调用甚至构造函数,那么考虑使用Spring驱动的native AspectJ weaving,而不是Spring的基于代理的AOP框架。框架

要强制使用CGLIB代理,请将aop:config元素的proxy target class属性的值设置为true,以下所示:函数

<aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
</aop:config>
复制代码

要在使用@Aspectj auto proxy支持时强制cglib代理,请将aop:aspectj-autoproxy元素的proxy-target-class属性设置为true,以下所示:this

<aop:aspectj-autoproxy proxy-target-class="true"/>
复制代码

AOP Proxies原理

SpringAOP是基于代理的,那什么是代理呢?spa

首先咱们考虑一个最简单的POJO对象:代理

public class SimplePojo implements Pojo {

    public void foo() {
        // this next method invocation is a direct call on the 'this' reference
        this.bar();
    }

    public void bar() {
        // some logic...
    }
}
复制代码

若是直接调用该对象的方法,则运行原理以下所示:code

image

调用方法以下:

public class Main {

    public static void main(String[] args) {
        Pojo pojo = new SimplePojo();
        // this is a direct method call on the 'pojo' reference
        pojo.foo();
    }
}
复制代码

若是是调用代理,则运行原理以下:

image

调用方法以下:

public class Main {

    public static void main(String[] args) {
        ProxyFactory factory = new ProxyFactory(new SimplePojo());
        factory.addInterface(Pojo.class);
        factory.addAdvice(new RetryAdvice());

        Pojo pojo = (Pojo) factory.getProxy();
        // this is a method call on the proxy!
        pojo.foo();
    }
}
复制代码

本文的例子请参考aop-proxy

更多教程请参考 flydean的博客

相关文章
相关标签/搜索