<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          spring多個(gè)AOP執(zhí)行先后順序

          共 4241字,需瀏覽 9分鐘

           ·

          2020-08-07 13:39


          眾所周知,spring聲明式事務(wù)是基于AOP實(shí)現(xiàn)的,那么,如果我們?cè)谕粋€(gè)方法自定義多個(gè)AOP,我們?nèi)绾沃付ㄋ麄兊膱?zhí)行順序呢?


          網(wǎng)上很多答案都是指定order,order越小越是最先執(zhí)行,這種也不能算是錯(cuò),但有些片面。


          配置AOP執(zhí)行順序的三種方式:

          1. 通過(guò)實(shí)現(xiàn)org.springframework.core.Ordered接口


            @Component??
            ????@Aspect??
            ????@Slf4j??
            ????public class MessageQueueAopAspect1 implements Ordered{@Override??
            ????????public int getOrder() {
            ????????????// TODO Auto-generated method stub
            ????????????return?2;
            ????????}
            ??????????
            ????}


          2. 通過(guò)注解


            @Component??
            ????@Aspect??
            ????@Slf4j??
            ????@Order(1)
            ????public class MessageQueueAopAspect1{
            ??????????
            ????????...
            ????}


          3. 通過(guò)配置文件配置


            <aop:config?expose-proxy="true">??
            ????????<aop:aspect?ref="aopBean"?order="0">????
            ????????????<aop:pointcut?id="testPointcut"??expression="@annotation(xxx.xxx.xxx.annotation.xxx)"/>????
            ????????????<aop:around?pointcut-ref="testPointcut"?method="doAround"?/>????
            ????????????aop:aspect>????
            ????aop:config>


          我們?cè)谕粋€(gè)方法上加以下兩個(gè)AOP,看看究竟。


          @Component??
          ????@Aspect??
          ????@Slf4j
          ????public?class?MessageQueueAopAspect1?implements?Ordered{
          ??????????
          ????????@Resource(name="actionMessageProducer")
          ????????private?IProducer actionProducer;
          ??????????
          ????????@Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire1)")
          ????????private?void?pointCutMethod()?{
          ????????}
          ??????????
          ????????//聲明前置通知
          ????????@Before("pointCutMethod()")
          ????????public?void?doBefore(JoinPoint point)?{
          ????????????log.info("MessageQueueAopAspect1:doBefore");
          ????????????return;
          ????????}
          ??????
          ????????//聲明后置通知
          ????????@AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")
          ????????public?void?doAfterReturning(JoinPoint point,Object returnValue)?{
          ????????????log.info("MessageQueueAopAspect1:doAfterReturning");
          ????????}
          ??????
          ????????//聲明例外通知
          ????????@AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
          ????????public?void?doAfterThrowing(Exception e)?{
          ????????????log.info("MessageQueueAopAspect1:doAfterThrowing");
          ????????}
          ??????
          ????????//聲明最終通知
          ????????@After("pointCutMethod()")
          ????????public?void?doAfter()?{
          ????????????log.info("MessageQueueAopAspect1:doAfter");
          ????????}
          ??????
          ????????//聲明環(huán)繞通知
          ????????@Around("pointCutMethod()")
          ????????public?Object doAround(ProceedingJoinPoint pjp)?throws?Throwable {
          ????????????log.info("MessageQueueAopAspect1:doAround-1");
          ????????????Object obj = pjp.proceed();
          ????????????log.info("MessageQueueAopAspect1:doAround-2");
          ????????????return?obj;
          ????????}
          ??????????
          ????????@Override??
          ????????public?int?getOrder()?{
          ????????????return?1001;
          ????????}
          ????}


          @Component??
          @Aspect??
          @Slf4j
          public?class?MessageQueueAopAspect2?implements?Ordered{
          ??????
          ????@Resource(name="actionMessageProducer")
          ????private?IProducer actionProducer;
          ??????
          ????@Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire2)")
          ????private?void?pointCutMethod()?{
          ????}
          ??????
          ??????
          ????//聲明前置通知
          ????@Before("pointCutMethod()")
          ????public?void?doBefore(JoinPoint point)?{
          ????????log.info("MessageQueueAopAspect2:doBefore");
          ????????return;
          ????}
          ??
          ????//聲明后置通知
          ????@AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")
          ????public?void?doAfterReturning(JoinPoint point,Object returnValue)?{
          ????????log.info("MessageQueueAopAspect2:doAfterReturning");
          ????}
          ??
          ????//聲明例外通知
          ????@AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")
          ????public?void?doAfterThrowing(Exception e)?{
          ????????log.info("MessageQueueAopAspect2:doAfterThrowing");
          ????}
          ??
          ????//聲明最終通知
          ????@After("pointCutMethod()")
          ????public?void?doAfter()?{
          ????????log.info("MessageQueueAopAspect2:doAfter");
          ????}
          ??
          ????//聲明環(huán)繞通知
          ????@Around("pointCutMethod()")
          ????public?Object doAround(ProceedingJoinPoint pjp)?throws?Throwable {
          ????????log.info("MessageQueueAopAspect2:doAround-1");
          ????????Object obj = pjp.proceed();
          ????????log.info("MessageQueueAopAspect2:doAround-2");
          ????????return?obj;
          ????}
          ??????
          ????@Override??
          ????public?int?getOrder()?{
          ????????return?1002;
          ????}
          }


          @Transactional(propagation=Propagation.REQUIRES_NEW)
          ????@MessageQueueRequire1??
          ????@MessageQueueRequire2??
          ????public PnrPaymentErrCode bidLoan(String id){
          ??????????????????...
          ???????????}


          看看執(zhí)行結(jié)果:



          從上面的測(cè)試我們看到,確實(shí)是order越小越是最先執(zhí)行,但更重要的是最先執(zhí)行的最后結(jié)束。


          這個(gè)不難理解,Spring AOP就是面向切面編程,什么是切面,畫(huà)一個(gè)圖來(lái)理解下:


          ? ? ? ? ?

          由此得出:spring aop就是一個(gè)同心圓,要執(zhí)行的方法為圓心,最外層的order最小。從最外層按照AOP1、AOP2的順序依次執(zhí)行doAround方法,doBefore方法。然后執(zhí)行method方法,最后按照AOP2、AOP1的順序依次執(zhí)行doAfter、doAfterReturn方法。也就是說(shuō)對(duì)多個(gè)AOP來(lái)說(shuō),先before的,一定后after。

          ? ? ? ??

          如果我們要在同一個(gè)方法事務(wù)提交后執(zhí)行自己的AOP,那么把事務(wù)的AOP order設(shè)置為2,自己的AOP order設(shè)置為1,然后在doAfterReturn里邊處理自己的業(yè)務(wù)邏輯。


          出處:cnblogs.com/panchanggui/p/12203066.html




          點(diǎn)個(gè)“在看”哦!

          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄片久久| 日韩黄色一级电影 | 亚洲色图欧美另类 | www.毛片av | 一区二区三区福利视频 |