Spring实践:面向切面编程(AOP)

原文链接:http://blog.csdn.net/zjf280441589/article/details/50816802


AOP引介


AOP(Aspect Oriented Programing)面向切面编程采用横向抽取机制,以取代传统的纵向继承体系的重复性代码(如性能监控/事务管理/安全检查/缓存实现等).

横向抽取代码复用: 基于代理技术,在不修改原来代码的前提下,对原有方法进行增强.


Spring AOP 历史


1.2开始, Spring开始支持AOP技术(Spring AOP).Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码.

2.0之后, 为了简化AOP开发, Spring开始支持AspectJ(一个基于Java的AOP框架)框架.


AOP相关术语


术语 中文 描述
Joinpoint 连接点 指那些被拦截到的点.在Spring中,这些点指方法(因为Spring只支持方法类型的连接点).
Pointcut 切入点 指需要(配置)被增强的Joinpoint.
Advice 通知/增强 指拦截到Joinpoint后要做的操作.通知分为前置通知/后置通知/异常通知/最终通知/环绕通知等.
Aspect 切面 切入点和通知的结合.
Target 目标对象 需要被代理(增强)的对象.
Proxy 代理对象 目标对象被AOP 织入 增强/通知后,产生的对象.
Weaving 织入 指把增强/通知应用到目标对象来创建代理对象过程(Spring采用动态代理织入,AspectJ采用编译期织入和类装载期织入).
Introduction 引介 一种特殊通知,在不修改类代码的前提下,可以在运行期为类动态地添加一些Method/Field(不常用).

其他关于AOP理论知识可参考AOP技术研究.


AOP实现


Spring AOP代理实现有两种:JDK动态代理和Cglib框架动态代理, JDK动态代理可以参考博客代理模式的动态代理部分, 在这里仅介绍CGLib框架实现.


cglib 动态代理


cglib(Code Generation Library)是一个开源/高性能/高质量的Code生成类库,可以在运行期动态扩展Java类与实现Java接口.

cglib比java.lang.reflect.Proxy更强的在于它不仅可以接管接口类的方法,还可以接管普通类的方法(cglib项目).从3.2开始, spring-core包中内置cglib类,因此可以不用添加额外依赖.


  • UserDAO(并没有实现接口)

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> jifang
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @since</span> 16/3/3 上午11:16.
 */</span>
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">UserDAO</span> {</span>

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">add</span>(Object o) {
        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"UserDAO -> Add: "</span> + o.toString());
    }

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">get</span>(Object o) {
        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"UserDAO -> Get: "</span> + o.toString());
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li></ul>


  • CGLibProxyFactory

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">CGLibProxyFactory</span> {</span>

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Object target;

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">CGLibProxyFactory</span>(Object target) {
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.target = target;
    }


    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Callback callback = <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">new</span> MethodInterceptor() {

        <span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
         *
         *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> obj   代理对象
         *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> method    当期调用方法
         *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> args  方法参数
         *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> proxy 被调用方法的代理对象(用于执行父类的方法)
         *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @return</span>
         *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @throws</span> Throwable
         */</span>
        <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">intercept</span>(Object obj, Method method, Object[] args, MethodProxy proxy) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Throwable {

            <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 前置增强</span>
            System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"+ Before Advice ..."</span>);

            <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 执行目标方法</span>
            <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">//Object result = method.invoke(target, args);</span>
            Object result = proxy.invoke(target, args);

            <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 后置增强</span>
            System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"+ After Advice ..."</span>);

            <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;
        }
    };

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">createProxy</span>() {

        <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 1. 创建Enhancer对象</span>
        Enhancer enhancer = <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Enhancer();

        <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 2. cglib创建代理, 对目标对象创建子对象</span>
        enhancer.setSuperclass(target.getClass());

        <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 3. 传入回调接口, 对目标增强</span>
        enhancer.setCallback(callback);

        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> enhancer.create();
    }

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">main</span>(String[] args) {
        UserDAO proxy = (UserDAO) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">new</span> CGLibProxyFactory(<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">new</span> UserDAO()).createProxy();
        proxy.get(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>);
        proxy.add(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"world"</span>);
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">27</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">28</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">29</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">30</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">31</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">32</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">33</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">34</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">35</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">36</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">37</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">38</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">39</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">40</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">41</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">42</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">43</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">44</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">45</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">46</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">47</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">48</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">49</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">50</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">51</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">52</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">53</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">54</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">55</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">56</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">57</li></ul>


AOP小结


Spring AOP的底层通过JDK/cglib动态代理为目标对象进行横向织入:

1) 若目标对象实现了接口,则Spring使用JDK的java.lang.reflect.Proxy代理.

2) 若目标对象没有实现接口,则Spring使用cglib库生成目标对象的子类.

Spring只支持方法连接点,不提供属性连接.

标记为final的方法不能被代理,因为无法进行覆盖.

程序应优先对针对接口代理,这样便于程序解耦/维护.


Spring AOP


AOP联盟为通知Advice定义了org.aopalliance.aop.Advice接口, Spring在Advice的基础上,根据通知在目标方法的连接点位置,扩充为以下五类:


通知 接口 描述
前置通知 MethodBeforeAdvice 在目标方法执行实施增强
后置通知 AfterReturningAdvice …执行实施增强
环绕通知 MethodInterceptor ..执行前后实施增强
异常抛出通知 ThrowsAdvice …抛出异常后实施增强
引介通知 IntroductionInterceptor 在目标类中添加新的方法和属性(少用)


  • 添加Spring的AOP依赖

使用Spring的AOP和AspectJ需要在pom.xml中添加如下依赖:

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">dependency</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">groupId</span>></span>org.springframework<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">groupId</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">artifactId</span>></span>spring-aop<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">artifactId</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">version</span>></span>${spring.version}<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">version</span>></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">dependency</span>></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">dependency</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">groupId</span>></span>org.springframework<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">groupId</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">artifactId</span>></span>spring-aspects<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">artifactId</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">version</span>></span>${spring.version}<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">version</span>></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">dependency</span>></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li></li></ul>


  • 定义Target

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> jifang
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @since</span> 16/3/3 下午2:50.
 */</span>
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">OrderService</span> {</span>

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> save();

    Integer delete(Integer param);
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li></ul>
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">OrderServiceImpl</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">OrderService</span> {</span>

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">save</span>() {
        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"添加..."</span>);
    }

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Integer <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">delete</span>(Integer param) {
        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"删除..."</span>);
        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> param;
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li></li></ul>


  • 定义Advice

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * 实现MethodInterceptor接口定义环绕通知
 *
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> jifang
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @since</span> 16/3/6 下午2:54.
 */</span>
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">ConcreteInterceptor</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">implements</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">MethodInterceptor</span> {</span>

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">invoke</span>(MethodInvocation invocation) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Throwable {
        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"前置通知 -> "</span>);

        Object result = invocation.proceed();

        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"<- 后置通知"</span>);

        <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li></li></ul>


Spring手动代理


  • 配置代理

Spring最原始的AOP支持, 手动指定目标对象与通知(没有使用AOP名称空间).

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:xsi</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xsi:schemaLocation</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd"</span>></span>

    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- target --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"service"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq.service.impl.OrderServiceImpl"</span>/></span>
    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- advice --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"advice"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq.advice.ConcreteInterceptor"</span>/></span>

    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"serviceProxy"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"org.springframework.aop.framework.ProxyFactoryBean"</span>></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">property</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"target"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">ref</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"service"</span>/></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">property</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"interceptorNames"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">value</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"advice"</span>/></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">property</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">name</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"proxyTargetClass"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">value</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"false"</span>/></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span>></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span>></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li></li></ul>


  • Client

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@RunWith</span>(SpringJUnit4ClassRunner.class)
<span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@ContextConfiguration</span>(locations = <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"classpath:spring/applicationContext.xml"</span>)
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">AOPClient</span> {</span>

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Autowired</span>
    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 必须指定使用代理对象名称, 否则不予代理</span>
    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Qualifier</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"serviceProxy"</span>)
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">private</span> OrderService service;

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Test</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">client</span>() {
        service.save();
        service.delete(<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">88</span>);
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15
</li></ul>

这种方式的缺陷在于每个Target都必须手动指定ProxyFactoryBean对其代理(不能批量指定),而且这种方式会在Spring容器中存在两份Target对象(代理前/代理后),浪费资源,且容易出错(比如没有指定@Qualifier).


Spring自动代理 – 引入AspectJ


通过AspectJ引入Pointcut切点定义


  • Target/Advice

同前


  • 定义切面表达式

  •  通过execution函数定义切点表达式(定义切点的方法切入) 
    execution(<访问修饰符> <返回类型><方法名>(<参数>)<异常>) 
    如: 
    1)  execution(public * *(..)) # 匹配所有 public方法. 
    2)  execution(* com.fq.dao.*(..)) # 匹配指定包下所有类方法(不包含子包) 
    3)  execution(* com.fq.dao..*(..)) # 匹配指定包下所有类方法(包含子包) 
    4)  execution(* com.fq.service.impl.OrderServiceImple.*(..)) # 匹配指定类所有方法 
    5)  execution(* com.fq.service.OrderService+.*(..)) # 匹配实现特定接口所有类方法 
    6)  execution(* save*(..)) # 匹配所有save开头的方法
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:xsi</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:aop</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/aop"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xsi:schemaLocation</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd"</span>></span>

    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- target --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"service"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq.service.impl.OrderServiceImpl"</span>/></span>
    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- advice --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"advice"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq.advice.ConcreteInterceptor"</span>/></span>

    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- 配置切面 : proxy-target-class确定是否使用CGLIB --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:config</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">proxy-target-class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"true"</span>></span>
        <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!--
            aop:pointcut : 切点定义
            aop:advisor: 定义Spring传统AOP的切面,只支持一个pointcut/一个advice
            aop:aspect : 定义AspectJ切面的,可以包含多个pointcut/多个advice
        --></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:pointcut</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"pointcut"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">expression</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>/></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:advisor</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">advice-ref</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"advice"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">pointcut-ref</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"pointcut"</span>/></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:config</span>></span>

<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span>></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li></li></ul>


  • Client

同前


AspectJ AOP


AspectJ是一个基于Java的AOP框架,提供了强大的AOP功能,其他很多AOP框架都借鉴或采纳了AspectJ的一些思想,Spring2.0以后增加了对AspectJ切点表达式支持(如上),并在Spring3.0之后与AspectJ进行了很好的集成.

在Java领域,AspectJ中的很多语法结构基本上已成为AOP领域的标准, 他定义了如下几类通知类型:

通知 接口 描述
前置通知 @Before 相当于BeforeAdvice
后置通知 @AfterReturning 相当于AfterReturningAdvice
环绕通知 @Around 相当于MethodInterceptor
抛出通知 @AfterThrowing 相当于ThrowAdvice
引介通知 @DeclareParents 相当于IntroductionInterceptor
最终final通知 @After 不管是否异常,该通知都会执行

新版本Spring,建议使用AspectJ方式开发以简化AOP配置.


AspectJ-XML-AOP


使用AspectJ编写Advice无需实现任何接口,而且可以将多个通知写入一个切面类.


前置通知


  • 定义通知

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> jifang
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @since</span> 16/3/3 下午5:38.
 */</span>
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">Aspect</span> {</span>

    <span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 无返回值
     */</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">before1</span>() {
        System.out.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"前置增强before1"</span>);
    }

    <span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
     * 还可以传入连接点参数 JoinPoint
     *
     *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> point
     */</span>
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">before2</span>(JoinPoint point) {
        System.out.printf(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"前置增强before2 %s%n"</span>, point.getKind());
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li></li></ul>


  • 装配

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:xsi</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:aop</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/aop"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:context</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/context"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xsi:schemaLocation</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"</span>></span>

    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">context:component-scan</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">base-package</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq.service"</span>/></span>

    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- 配置切面通知 --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">bean</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"advice"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">class</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq.advice.Aspect"</span>/></span>

    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- AOP切面配置 --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:config</span>></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:aspect</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">ref</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"advice"</span>></span>
            <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:pointcut</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">id</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"pointcut"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">expression</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>/></span>
            <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:before</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">method</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"before1"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">pointcut-ref</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"pointcut"</span>/></span>
            <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:before</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">method</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"before2"</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">pointcut-ref</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"pointcut"</span>/></span>
        <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:aspect</span>></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:config</span>></span>

<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span>></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">27</li><li></li></ul>


  • 前置通知小结

前置通知会保证在目标方法执行前执行;

前置通知默认不能阻止目标方法执行(但如果通知抛出异常,则目标方法无法执行);

可以通过JoinPoint参数获得当前拦截对象和方法等信息.


后置通知


  • 定义通知

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">afterReturning</span>(JoinPoint point, Object result) {
    System.<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.printf(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"后置增强, 结果为 %s%n"</span>, result);
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li></li></ul>


  • 装配

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><aop:after-returning <span class="hljs-function" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">method</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">afterReturning</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">returning</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">result</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>-<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">ref</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>"/></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li></ul>

后置通知可以获得方法返回值,但在配置文件定义返回值参数名必须与后置通知方法参数名一致(如result).


环绕通知


  • 定义通知

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">public Object around(ProceedingJoinPoint point) throws Throwable {
    System<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.printf</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"环绕前置增强 method: %s, args: %s%n"</span>, point<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.toShortString</span>(), Arrays<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.toString</span>(point<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getArgs</span>()))<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    Object result = point<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.proceed</span>(point<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getArgs</span>())<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    System<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.printf</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"环绕后置增强 result: %s%n"</span>, result)<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    return result<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li></li></ul>

  • 装配

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><aop:around <span class="hljs-function" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">method</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">around</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">arg</span>-<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">names</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">point</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>-<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">ref</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>"/></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li></ul>

环绕通知可以实现任何通知的效果, 甚至可以阻止目标方法的执行.


抛出通知


  • 定义通知

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">private static final Logger LOGGER = LoggerFactory<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getLogger</span>(Aspect<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.class</span>)<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

public void afterThrowing(JoinPoint point, Throwable ex) {
    String message = new StringBuilder(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"method "</span>)<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.append</span>(point<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getSignature</span>()<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.append</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">" error"</span>)<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.toString</span>()<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    System<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(message)<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    LOGGER<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.error</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"{},"</span>, message, ex)<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li></li></ul>

  • 装配

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><aop:after-throwing <span class="hljs-function" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">method</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">afterThrowing</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">throwing</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">ex</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>-<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">ref</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>"/></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li></ul>

throwing属性指定异常对象名, 该名称应和方法定义参数名一致.


最终通知


  • 定义通知

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">after</span>(JoinPoint point) {
    System.<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"最终通知, 释放资源"</span>);
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li></li></ul>

  • 装配

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><aop:after <span class="hljs-function" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">method</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">after</span>" <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>-<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">ref</span>="<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>"/></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li></ul>

无论目标方法是否出现异常,该通知都会执行(类似finally代码块, 应用场景为释放资源).


AspectJ-Annotation-AOP


@AspectJ是AspectJ 1.5新增功能,可以通过JDK注解技术,直接在Bean类中定义切面.

AspectJ预定义的注解有:@Before/@AfterReturning/@Around/@AfterThrowing/@DeclareParents/@After.描述同前.

使用AspectJ注解AOP需要在applicationContext.xml文件中开启注解自动代理功能:

<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-pi" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:xsi</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:aop</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/aop"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:context</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/context"</span>
       <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">xsi:schemaLocation</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd"</span>></span>

    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- 批量扫描@Component --></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">context:component-scan</span> <span class="hljs-attribute" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">base-package</span>=<span class="hljs-value" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 136, 0);">"com.fq"</span>/></span>
    <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;"><!-- 启用注解自动代理@Aspect--></span>
    <span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">aop:aspectj-autoproxy</span>/></span>
<span class="hljs-tag" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(0, 0, 136);">beans</span>></span></code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li></ul>


  • OrderService/Client

同前


@Before


  • Aspect

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @Aspect</span>: 指定是一个切面
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @Component</span>: 指定可以被Spring容器扫描到
 */</span>
<span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Aspect</span>
<span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Component</span>
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">CustomAspect</span> {</span>

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Before</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>)
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">before</span>(JoinPoint point) {
        System.out.printf(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"前置增强before2 %s%n"</span>, point.getKind());
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li></li></ul>


@AfterReturning


<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@AfterReturning(<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">value</span> = <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"execution(* com.fq.service.impl.OrderServiceImpl.d*(..))"</span>, returning = <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"result"</span>)
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">afterReturning</span>(JoinPoint point, Object result) {
    System.<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.printf(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"后置增强, 结果为 %s%n"</span>, result);
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li></li></ul>


@Around


<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Around</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>)
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> Object <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">around</span>(ProceedingJoinPoint point) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> Throwable {
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">long</span> start = System.currentTimeMillis();
    Object result = point.proceed(point.getArgs());
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">long</span> time = System.currentTimeMillis() - start;

    System.out.printf(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"method %s invoke consuming %d ms%n"</span>, point.toLongString(), time);

    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li></ul>

如果不调用ProceedingJoinPoint的proceed方法,那么目标方法就不执行了.


@AfterThrowing


<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@AfterThrowing(value = <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>, throwing = <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"ex"</span>)
public void afterThrowing(JoinPoint point, Throwable ex) {
    String message = new StringBuilder(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"method "</span>)<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.append</span>(point<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getSignature</span>()<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.append</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">" error"</span>)<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.toString</span>()<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    System<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(message)<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    LOGGER<span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">.error</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"{},"</span>, message, ex)<span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li></li></ul>


@After


<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@After(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>)
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">after</span>(JoinPoint point) {
    System.<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"最终通知, 释放资源"</span>);
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li></li></ul>


@Pointcut定义切点


对于重复的切点,可以使用@Pointcut进行定义, 然后在通知注解内引用.


  • 定义切点方法

无参/无返回值/方法名为切点名:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> jifang
 *<span class="hljs-javadoctag" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;"> @since</span> 16/3/4 上午11:47.
 */</span>
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="margin: 0px; padding: 0px; box-sizing: border-box;"><span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box; color: rgb(102, 0, 102);">OrderServicePointcut</span> {</span>

    <span class="hljs-annotation" style="margin: 0px; padding: 0px; color: rgb(155, 133, 157); box-sizing: border-box;">@Pointcut</span>(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"execution(* com.fq.service.impl.OrderServiceImpl.*(..))"</span>)
    <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">pointcut</span>() {
    }
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li></li></ul>


  • 引用切点

在Advice上像调用方法一样引用切点:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">@After(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"OrderServicePointcut.pointcut()"</span>)
<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="margin: 0px; padding: 0px; box-sizing: border-box;">after</span>(JoinPoint point) {
    System.<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.println(<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"最终通知, 释放资源"</span>);
}</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li></ul>

1) 如果切点与切面在同一个类内, 可省去类名前缀; 
2) 当需要通知多个切点时,可以使用||/&&进行连接.


小结


通知 描述
前置通知 权限控制(少用)
后置通知 少用
环绕通知 权限控制/性能监控/缓存实现/事务管理
异常通知 发生异常后,记录错误日志
最终通知 释放资源


  • 添加Spring的AOP依赖

  • 添加Spring的AOP依赖

  • Target/Advice同前

  • 定义切面表达式


  • Target/Advice

同前


  • Client

同前


  • Client

同前


猜你喜欢

转载自blog.csdn.net/yulidrff/article/details/51164574