切面:@Aspect、切點:@PointCut

舉個例子:
一個類(Show)裏面有一個表演(display)的方法,在表演之前,應該有致辭(say)的方法,在表演之後,應該有鼓掌(hand)的方法。
爲了高內聚低耦合,表演的方法應該單獨封裝在一個類裏面,致辭和鼓掌的方法應該另外封裝,但在調用時必須按照順序來調用執行。這時候就需要設置切面和切點了!

切面應該設置在致辭(say)和鼓掌(hand)方法所在的類上面,同時,要在類裏面配置切點,類似:

 //定義切點--功能權限更新com.eastcom.bbf.bs.management.service
@Pointcut("execution( com.eastcom.bbf.bs.management.service.FunctionRightsService.updateFunctionRight(..))")
  private void updateFunctionRightPointCut() {
        // 這是一個標記方法
  }*    
    》》即:@PointCut()裏面應該配置 表演(display)方法的路徑
如果上面沒有定義標記方法,則下面的pointcut 應該等於"execution(......)"

@AfterReturning(pointcut = "updateFunctionRightPointCut()",returning = "rvt")
  public void afterUpdateFunctionRight(JoinPoint joinPoint,String rvt) {
    **// 此方法是在切入點方法執行之後執行**
        // joinPoint.getArgs() 就是獲取切入點方法的入參
        // rvt 就是切入點方法的返回值
        ..............
        》》此方法相當於 鼓掌(hand)方法。
  }
@Before("updateFunctionRightPointCut()")
  public void beforeSaveServiceNode(JoinPoint joinPoint) {
    **  // 此方法在切入點之前執行**
    ServiceNode node = (ServiceNode) joinPoint.getArgs()[0];
    .............
        》》此方法相當於 致辭(say) 方法。
  }

這樣配置完成時,在調用display(切入點)方法時,就會自動調用致辭(say)和鼓掌(hand)方法了。

測試類似代碼時,應該在切點的方法裏面打斷點,然後在想要執行的方法裏面打斷點。


 

此外,在項目中遇到一個問題就是,調用不到一個類中的一個方法。然後也可以通過設置切點、切面來解決。
如:
XXFilter類裏面有個 updateInit()方法,因爲是filter不能自動注入,外面無法調用這個方法。br/>解決:
自己寫一個XXService類(設置自動注入@Service),在裏面定義一個update()方法,方法體內爲空,
在XXFilter類上面設置@Aspect,在裏面設置@PointCut(“execution(update()方法的路徑)”),
然後

@AfterReturning(...)
void  xxUpdate(){
    // 在裏面只是調用updateInit()方法。
    updateInit( )
}

這樣就可以通過 XXService調用update()方法來調用updateInit()方法了。

  1. 通知、增強處理(Advice): 就是你想要的功能,你給先定義好,然後在想用的地方用一下,包含Aspect的一段處理代碼。
  2. 連接點(JoinPoint): 就是spring允許你是通知(Advice)的地方,基本每個方法的前、後(兩者都有也行),或拋出異常時都可以是連接點,spring只支持方法連接點。其他如AspectJ還可以讓你在構造器或屬性注入時都行,不過只要記住,和方法有關的前前後後都是連接點。連接點就是爲了獲取切點方法的相關信息(所在的類、入參、方法等)
  3. 切入點(Pointcut) :上面說的連接點的基礎上,來定義切入點,你的一個類裏,有15個方法,那就有十幾個連接點了,但是並不想在所有方法附近都使用通知(使用叫織入),只是想讓其中幾個,在調用這幾個方法之前、之後或者拋出異常時乾點什麼,那麼就用切入點來定義這幾個方法,讓切點來篩選連接點,選中那幾個你想要的方法。
  4. 切面(Aspect) :切面是通知和切入點的結合。連接點就是爲了方便理解切點的,明白這個概念就行了。通知說明了幹什麼和什麼時候幹(什麼時候通過方法名中的befor,after,around等就能知道),切入點說明了在哪幹(指定到底是哪個方法),這就是一個完整的切面定義。
@Aspect //聲明切面,標記類  
public class Wly {  

@Pointcut("execution(* *.perform(..))") //定義切點,標記方法  
public void performance() {}  

@Before("performance()")  //切點之前執行  
public ....        

@AfterReturning("performance()")  //切點執行成功之後執行  
public ...  
//  @After("....")   // 在切點之後執行,無論方法執行成功與否

@AfterThrowing("performance()")  //切點拋出異常後執行  
public ...  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章