AOP 执行顺序
情况一: 一个方法只被一个Aspect类拦截
当一个方法只被一个Aspect拦截时,这个Aspect中的不同advice是按照怎样的顺序进行执行的呢?请看:
添加 PointCut类
该pointcut用来拦截test包下的所有类中的所有方法。
1 2 3 4 5 6 7 8 9 10 |
<span class="hljs-keyword js-evernote-checked" data-evernote-id="523">package</span> test; <span class="hljs-keyword js-evernote-checked" data-evernote-id="524">import</span> org.aspectj.lang.annotation.Pointcut; <span class="hljs-keyword js-evernote-checked" data-evernote-id="525">public</span> <span class="hljs-class js-evernote-checked" data-evernote-id="526"><span class="hljs-keyword js-evernote-checked" data-evernote-id="527">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="528">PointCuts</span> {</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="529">@Pointcut</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="530">"within(test.*)"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="531">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="532">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="533">aopDemo</span>() { } } |
添加Aspect类
该类中的advice将会用到上面的pointcut,使用方法请看各个advice的value属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<span class="hljs-keyword js-evernote-checked" data-evernote-id="547">package</span> test; <span class="hljs-keyword js-evernote-checked" data-evernote-id="548">import</span> org.aspectj.lang.JoinPoint; <span class="hljs-keyword js-evernote-checked" data-evernote-id="549">import</span> org.aspectj.lang.ProceedingJoinPoint; <span class="hljs-keyword js-evernote-checked" data-evernote-id="550">import</span> org.aspectj.lang.annotation.*; <span class="hljs-keyword js-evernote-checked" data-evernote-id="551">import</span> org.springframework.stereotype.Component; <span class="hljs-annotation js-evernote-checked" data-evernote-id="552">@Component</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="553">@Aspect</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="554">public</span> <span class="hljs-class js-evernote-checked" data-evernote-id="555"><span class="hljs-keyword js-evernote-checked" data-evernote-id="556">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="557">Aspect1</span> {</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="558">@Before</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="559">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="560">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="561">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="562">before</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="563">"[Aspect1] before advise"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="564">@Around</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="565">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="566">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="567">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="568">around</span>(ProceedingJoinPoint pjp) <span class="hljs-keyword js-evernote-checked" data-evernote-id="569">throws</span> Throwable{ System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="570">"[Aspect1] around advise 1"</span>); pjp.proceed(); System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="571">"[Aspect1] around advise2"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="572">@AfterReturning</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="573">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="574">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="575">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="576">afterReturning</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="577">"[Aspect1] afterReturning advise"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="578">@AfterThrowing</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="579">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="580">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="581">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="582">afterThrowing</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="583">"[Aspect1] afterThrowing advise"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="584">@After</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="585">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="586">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="587">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="588">after</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="589">"[Aspect1] after advise"</span>); } } |
添加测试用Controller
添加一个用于测试的controller,这个controller中只有一个方法,但是它会根据参数值的不同,会作出不同的处理:一种是正常返回一个对象,一种是抛出异常(因为我们要测试@AfterThrowing这个advice)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<span class="hljs-keyword js-evernote-checked" data-evernote-id="631">package</span> test; <span class="hljs-keyword js-evernote-checked" data-evernote-id="632">import</span> test.exception.TestException; <span class="hljs-keyword js-evernote-checked" data-evernote-id="633">import</span> org.springframework.http.HttpStatus; <span class="hljs-keyword js-evernote-checked" data-evernote-id="634">import</span> org.springframework.web.bind.annotation.*; <span class="hljs-annotation js-evernote-checked" data-evernote-id="635">@RestController</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="636">@RequestMapping</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="637">"/aop"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="638">public</span> <span class="hljs-class js-evernote-checked" data-evernote-id="639"><span class="hljs-keyword js-evernote-checked" data-evernote-id="640">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="641">AopTestController</span> {</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="642">@ResponseStatus</span>(HttpStatus.OK) <span class="hljs-annotation js-evernote-checked" data-evernote-id="643">@RequestMapping</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="644">"/test"</span>, method = RequestMethod.GET) <span class="hljs-keyword js-evernote-checked" data-evernote-id="645">public</span> Result <span class="hljs-title js-evernote-checked" data-evernote-id="646">test</span>(@RequestParam <span class="hljs-keyword js-evernote-checked" data-evernote-id="647">boolean</span> throwException) { <span class="hljs-comment js-evernote-checked" data-evernote-id="648">// case 1</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="649">if</span> (throwException) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="650">"throw an exception"</span>); <span class="hljs-keyword js-evernote-checked" data-evernote-id="651">throw</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="652">new</span> TestException(<span class="hljs-string js-evernote-checked" data-evernote-id="653">"mock a server exception"</span>); } <span class="hljs-comment js-evernote-checked" data-evernote-id="654">// case 2</span> System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="655">"test OK"</span>); <span class="hljs-keyword js-evernote-checked" data-evernote-id="656">return</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="657">new</span> Result() {{ <span class="hljs-keyword js-evernote-checked" data-evernote-id="658">this</span>.setId(<span class="hljs-number js-evernote-checked" data-evernote-id="659">111</span>); <span class="hljs-keyword js-evernote-checked" data-evernote-id="660">this</span>.setName(<span class="hljs-string js-evernote-checked" data-evernote-id="661">"mock a Result"</span>); }}; } <span class="hljs-keyword js-evernote-checked" data-evernote-id="662">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="663">static</span> <span class="hljs-class js-evernote-checked" data-evernote-id="664"><span class="hljs-keyword js-evernote-checked" data-evernote-id="665">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="666">Result</span> {</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="667">private</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="668">int</span> id; <span class="hljs-keyword js-evernote-checked" data-evernote-id="669">private</span> String name; <span class="hljs-keyword js-evernote-checked" data-evernote-id="670">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="671">int</span> <span class="hljs-title js-evernote-checked" data-evernote-id="672">getId</span>() { <span class="hljs-keyword js-evernote-checked" data-evernote-id="673">return</span> id; } <span class="hljs-keyword js-evernote-checked" data-evernote-id="674">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="675">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="676">setId</span>(<span class="hljs-keyword js-evernote-checked" data-evernote-id="677">int</span> id) { <span class="hljs-keyword js-evernote-checked" data-evernote-id="678">this</span>.id = id; } <span class="hljs-keyword js-evernote-checked" data-evernote-id="679">public</span> String <span class="hljs-title js-evernote-checked" data-evernote-id="680">getName</span>() { <span class="hljs-keyword js-evernote-checked" data-evernote-id="681">return</span> name; } <span class="hljs-keyword js-evernote-checked" data-evernote-id="682">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="683">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="684">setName</span>(String name) { <span class="hljs-keyword js-evernote-checked" data-evernote-id="685">this</span>.name = name; } } } |
测试 正常情况
在浏览器直接输入以下的URL,回车:
1 |
<span class="hljs-symbol js-evernote-checked" data-evernote-id="737">http:</span>/<span class="hljs-regexp js-evernote-checked" data-evernote-id="738">/192.168.142.8:7070/aoptest</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="739">/v1/aop</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="740">/test?throwException=false</span> |
我们会看到输出的结果是:
1 2 3 4 5 6 |
<span class="hljs-attr_selector js-evernote-checked" data-evernote-id="744">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="745">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="746">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="747">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="748">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="749">advise</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="750">test</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="751">OK</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="752">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="753">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="754">advise2</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="755">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="756">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="757">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="758">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="759">afterReturning</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="760">advise</span> |
测试 异常情况
在浏览器中直接输入以下的URL,回车:
1 |
<span class="hljs-symbol js-evernote-checked" data-evernote-id="770">http:</span>/<span class="hljs-regexp js-evernote-checked" data-evernote-id="771">/192.168.142.8:7070/aoptest</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="772">/v1/aop</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="773">/test?throwException=true</span> |
我们会看到输出的结果是:
1 2 3 4 5 |
<span class="hljs-attr_selector js-evernote-checked" data-evernote-id="777">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="778">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="779">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="780">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="781">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="782">advise</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="783">throw</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="784">an</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="785">exception</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="786">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="787">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="788">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="789">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="790">afterThrowing</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="791">advise</span> |
结论
在一个方法只被一个aspect类拦截时,aspect类内部的 advice 将按照以下的顺序进行执行:
正常情况:
异常情况:
情况二: 同一个方法被多个Aspect类拦截
此处举例为被两个aspect类拦截。
有些情况下,对于两个不同的aspect类,不管它们的advice使用的是同一个pointcut,还是不同的pointcut,都有可能导致同一个方法被多个aspect类拦截。那么,在这种情况下,这多个Aspect类中的advice又是按照怎样的顺序进行执行的呢?请看:
pointcut类保持不变
添加一个新的aspect类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<span class="hljs-keyword js-evernote-checked" data-evernote-id="811">package</span> test; <span class="hljs-keyword js-evernote-checked" data-evernote-id="812">import</span> org.aspectj.lang.JoinPoint; <span class="hljs-keyword js-evernote-checked" data-evernote-id="813">import</span> org.aspectj.lang.ProceedingJoinPoint; <span class="hljs-keyword js-evernote-checked" data-evernote-id="814">import</span> org.aspectj.lang.annotation.*; <span class="hljs-keyword js-evernote-checked" data-evernote-id="815">import</span> org.springframework.stereotype.Component; <span class="hljs-annotation js-evernote-checked" data-evernote-id="816">@Component</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="817">@Aspect</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="818">public</span> <span class="hljs-class js-evernote-checked" data-evernote-id="819"><span class="hljs-keyword js-evernote-checked" data-evernote-id="820">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="821">Aspect2</span> {</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="822">@Before</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="823">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="824">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="825">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="826">before</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="827">"[Aspect2] before advise"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="828">@Around</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="829">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="830">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="831">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="832">around</span>(ProceedingJoinPoint pjp) <span class="hljs-keyword js-evernote-checked" data-evernote-id="833">throws</span> Throwable{ System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="834">"[Aspect2] around advise 1"</span>); pjp.proceed(); System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="835">"[Aspect2] around advise2"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="836">@AfterReturning</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="837">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="838">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="839">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="840">afterReturning</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="841">"[Aspect2] afterReturning advise"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="842">@AfterThrowing</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="843">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="844">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="845">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="846">afterThrowing</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="847">"[Aspect2] afterThrowing advise"</span>); } <span class="hljs-annotation js-evernote-checked" data-evernote-id="848">@After</span>(value = <span class="hljs-string js-evernote-checked" data-evernote-id="849">"test.PointCuts.aopDemo()"</span>) <span class="hljs-keyword js-evernote-checked" data-evernote-id="850">public</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="851">void</span> <span class="hljs-title js-evernote-checked" data-evernote-id="852">after</span>(JoinPoint joinPoint) { System.out.println(<span class="hljs-string js-evernote-checked" data-evernote-id="853">"[Aspect2] after advise"</span>); } } |
测试用Controller也不变
还是使用上面的那个Controller。但是现在 aspect1 和 aspect2 都会拦截该controller中的方法。
下面继续进行测试!
测试 正常情况
在浏览器直接输入以下的URL,回车:
1 |
<span class="hljs-symbol js-evernote-checked" data-evernote-id="898">http:</span>/<span class="hljs-regexp js-evernote-checked" data-evernote-id="899">/192.168.142.8:7070/aoptest</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="900">/v1/aop</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="901">/test?throwException=false</span> |
我们会看到输出的结果是:
1 2 3 4 5 6 7 8 9 10 11 |
<span class="hljs-attr_selector js-evernote-checked" data-evernote-id="905">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="906">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="907">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="908">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="909">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="910">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="911">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="912">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="913">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="914">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="915">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="916">advise</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="917">test</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="918">OK</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="919">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="920">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="921">advise2</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="922">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="923">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="924">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="925">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="926">afterReturning</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="927">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="928">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="929">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="930">advise2</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="931">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="932">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="933">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="934">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="935">afterReturning</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="936">advise</span> |
但是这个时候,我不能下定论说 aspect2 肯定就比 aspect1 先执行。
不信?你把服务务器重新启动一下,再试试,说不定你就会看到如下的执行结果:
1 2 3 4 5 6 7 8 9 10 11 |
[Aspect1] around advise <span class="hljs-number js-evernote-checked" data-evernote-id="951">1</span> [Aspect1] before advise [Aspect2] around advise <span class="hljs-number js-evernote-checked" data-evernote-id="952">1</span> [Aspect2] before advise test OK [Aspect2] around advise2 [Aspect2] after advise [Aspect2] afterReturning advise [Aspect1] around advise2 [Aspect1] after advise [Aspect1] afterReturning advise |
也就是说,这种情况下, aspect1 和 aspect2 的执行顺序是未知的。那怎么解决呢?不急,下面会给出解决方案。
测试 异常情况
在浏览器中直接输入以下的URL,回车:
1 |
<span class="hljs-symbol js-evernote-checked" data-evernote-id="968">http:</span>/<span class="hljs-regexp js-evernote-checked" data-evernote-id="969">/192.168.142.8:7070/aoptest</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="970">/v1/aop</span><span class="hljs-regexp js-evernote-checked" data-evernote-id="971">/test?throwException=true</span> |
- 1
我们会看到输出的结果是:
1 2 3 4 5 6 7 8 9 |
<span class="hljs-attr_selector js-evernote-checked" data-evernote-id="975">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="976">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="977">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="978">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="979">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="980">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="981">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="982">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="983">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="984">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="985">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="986">advise</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="987">throw</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="988">an</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="989">exception</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="990">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="991">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="992">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="993">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="994">afterThrowing</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="995">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="996">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="997">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="998">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="999">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1000">afterThrowing</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1001">advise</span> |
同样地,如果把服务器重启,然后再测试的话,就可能会看到如下的结果:
1 2 3 4 5 6 7 8 9 |
<span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1013">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1014">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1015">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1016">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1017">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1018">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1019">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1020">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1021">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1022">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1023">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1024">advise</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1025">throw</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1026">an</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1027">exception</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1028">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1029">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1030">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1031">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1032">afterThrowing</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1033">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1034">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1035">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1036">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1037">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1038">afterThrowing</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1039">advise</span> |
也就是说,同样地,异常情况下, aspect1 和 aspect2 的执行顺序也是未定的。
那么在 情况二 下,如何指定每个 aspect 的执行顺序呢?
方法有两种:
- 实现org.springframework.core.Ordered接口,实现它的getOrder()方法
- 给aspect添加@Order注解,该注解全称为:org.springframework.core.annotation.Order
不管采用上面的哪种方法,都是值越小的 aspect 越先执行。
比如,我们为 apsect1 和 aspect2 分别添加 @Order 注解,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="hljs-annotation js-evernote-checked" data-evernote-id="1058">@Order</span>(<span class="hljs-number js-evernote-checked" data-evernote-id="1059">5</span>) <span class="hljs-annotation js-evernote-checked" data-evernote-id="1060">@Component</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="1061">@Aspect</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="1062">public</span> <span class="hljs-class js-evernote-checked" data-evernote-id="1063"><span class="hljs-keyword js-evernote-checked" data-evernote-id="1064">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="1065">Aspect1</span> {</span> <span class="hljs-comment js-evernote-checked" data-evernote-id="1066">// ...</span> } <span class="hljs-annotation js-evernote-checked" data-evernote-id="1067">@Order</span>(<span class="hljs-number js-evernote-checked" data-evernote-id="1068">6</span>) <span class="hljs-annotation js-evernote-checked" data-evernote-id="1069">@Component</span> <span class="hljs-annotation js-evernote-checked" data-evernote-id="1070">@Aspect</span> <span class="hljs-keyword js-evernote-checked" data-evernote-id="1071">public</span> <span class="hljs-class js-evernote-checked" data-evernote-id="1072"><span class="hljs-keyword js-evernote-checked" data-evernote-id="1073">class</span> <span class="hljs-title js-evernote-checked" data-evernote-id="1074">Aspect2</span> {</span> <span class="hljs-comment js-evernote-checked" data-evernote-id="1075">// ...</span> } |
这样修改之后,可保证不管在任何情况下, aspect1 中的 advice 总是比 aspect2 中的 advice 先执行。如下图所示:
注意点
-
如果在同一个 aspect 类中,针对同一个 pointcut,定义了两个相同的 advice(比如,定义了两个 @Before),那么这两个 advice 的执行顺序是无法确定的,哪怕你给这两个 advice 添加了 @Order 这个注解,也不行。这点切记。
-
对于@Around这个advice,不管它有没有返回值,但是必须要方法内部,调用一下 pjp.proceed();否则,Controller 中的接口将没有机会被执行,从而也导致了 @Before这个advice不会被触发。比如,我们假设正常情况下,执行顺序为”aspect2 -> apsect1 -> controller”,如果,我们把 aspect1中的@Around中的 pjp.proceed();给删掉,那么,我们看到的输出结果将是:
1 2 3 4 5 6 7 8 9 |
<span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1098">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1099">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1100">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1101">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1102">before</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1103">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1104">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1105">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1106">advise</span> 1 <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1107">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1108">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1109">advise2</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1110">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1111">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1112">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1113">[Aspect1]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1114">afterReturning</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1115">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1116">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1117">around</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1118">advise2</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1119">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1120">after</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1121">advise</span> <span class="hljs-attr_selector js-evernote-checked" data-evernote-id="1122">[Aspect2]</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1123">afterReturning</span> <span class="hljs-tag js-evernote-checked" data-evernote-id="1124">advise</span> |
从结果可以发现, Controller 中的 接口 未被执行,aspect1 中的 @Before advice 也未被执行。
发表评论