欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring AOP執(zhí)行先后順序?qū)嵗斀?/h1>
 更新時(shí)間:2020年01月22日 15:20:53   作者:panchanggui  
這篇文章主要介紹了Spring AOP執(zhí)行先后順序?qū)嵗斀?文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這篇文章主要介紹了Spring AOP執(zhí)行先后順序?qū)嵗斀?文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

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

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

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

通過(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; 
  } 
   
} 

通過(guò)注解

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

通過(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<MessageQueueInfo> 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<MessageQueueInfo> 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ù)邏輯。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)api加密的示例代碼

    SpringBoot實(shí)現(xiàn)api加密的示例代碼

    在項(xiàng)目中,為了保證數(shù)據(jù)的安全,我們常常會(huì)對(duì)傳遞的數(shù)據(jù)進(jìn)行加密。本文主要介紹了SpringBoot實(shí)現(xiàn)api加密的示例代碼,感興趣的小伙伴們可以參考一下
    2021-07-07
  • SpringBoot整合Netty實(shí)現(xiàn)WebSocket的示例代碼

    SpringBoot整合Netty實(shí)現(xiàn)WebSocket的示例代碼

    本文主要介紹了SpringBoot整合Netty實(shí)現(xiàn)WebSocket的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Java利用openoffice將doc、docx轉(zhuǎn)為pdf實(shí)例代碼

    Java利用openoffice將doc、docx轉(zhuǎn)為pdf實(shí)例代碼

    這篇文章主要介紹了Java利用openoffice將doc、docx轉(zhuǎn)為pdf實(shí)例代碼,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Hibernate對(duì)數(shù)據(jù)庫(kù)刪除、查找、更新操作實(shí)例代碼

    Hibernate對(duì)數(shù)據(jù)庫(kù)刪除、查找、更新操作實(shí)例代碼

    本篇文章主要介紹了Hibernate對(duì)數(shù)據(jù)庫(kù)刪除、查找、更新操作實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼

    SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼

    這篇文章主要為大家介紹了SpringMVC4.3解析器HandlerMethodArgumentResolver接口源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • java使用ZipInputStream實(shí)現(xiàn)讀取和寫(xiě)入zip文件

    java使用ZipInputStream實(shí)現(xiàn)讀取和寫(xiě)入zip文件

    zip文檔可以以壓縮格式存儲(chǔ)一個(gè)或多個(gè)文件,本文主要為大家詳細(xì)介紹了java如何使用ZipInputStream讀取Zip文檔與寫(xiě)入,需要的小伙伴可以參考下
    2023-11-11
  • 深入講解java線程與synchronized關(guān)鍵字

    深入講解java線程與synchronized關(guān)鍵字

    Java 中多線程的同步依靠的是對(duì)象鎖機(jī)制,synchronized關(guān)鍵字就是利用了封裝對(duì)象鎖來(lái)實(shí)現(xiàn)對(duì)共享資源的互斥訪問(wèn)。下面這篇文章主要介紹了java線程與synchronized關(guān)鍵字的相關(guān)資料,需要的朋友可以參考下。
    2017-03-03
  • java自定義序列化的具體使用

    java自定義序列化的具體使用

    本文主要介紹了java自定義序列化的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • JDBC SQL語(yǔ)法

    JDBC SQL語(yǔ)法

    結(jié)構(gòu)化查詢語(yǔ)言(SQL)是一種標(biāo)準(zhǔn)化的語(yǔ)言,它允許你在數(shù)據(jù)庫(kù)上執(zhí)行操作,如創(chuàng)建項(xiàng)目,讀取內(nèi)容,內(nèi)容更新和刪除條目
    2014-03-03
  • java顯示當(dāng)前的系統(tǒng)時(shí)間

    java顯示當(dāng)前的系統(tǒng)時(shí)間

    這篇文章主要介紹了java如何顯示當(dāng)前的系統(tǒng)時(shí)間,代碼很簡(jiǎn)單,自己可以自定義顯示的系統(tǒng)時(shí)間的顏色和字體,需要的朋友可以參考下
    2015-10-10

最新評(píng)論