Spring In Action--02(詳解AOP,AOP實例,AOP基本原理)

 

目錄

 

1.AOP概念理解

2.切點表達式的構成

 3.Spring AOP實例:

 4.Spring AOP的原理:


1.AOP概念理解

   軟件開發中散佈於應用中多處的功能被稱爲橫切關注點,把這些橫切關注點與業務邏輯分離,正是面向切面編程所要關注的問題,AOP是一種編程的範式,類似於面向過程,面向函數編程,面向對象編程一樣。另外他解決的是特定的問題而不是所有的問題。

  Spring AOP 構建在動態代理的基礎上,因此Spring 對 AOP的支持侷限於方法攔截,如果需要方法攔截之外的連接點的攔截功能,那麼我們可以利用AspectJ來補充Spring AOP的功能。

 AOP相關注解
        @EnableAspectJAutoProxy
        @Aspect
        @PointCut
        @Before、@Around、@After
        @AfterReturning
        @AfterThrowing

  AOP的初衷是什麼?第一個初衷就是消除重複的代碼。第二個初衷是將關注點分離:

       

 使用AOP的好處:

 AOP的使用場景:

 

 

 橫切關注點被模塊化爲特殊的類,這個類就被稱爲切面

   通知定義了切面是什麼以及何時使用,通知包含了需要應用於多個應用對象的橫切行爲。

   連接點是在應用執行過程中能夠插入切面的一個點。,是程序執行過程中能夠應用通知的所有點。

   切點的定義會匹配通知所要織人的一個或多個連接點。切點定義了通知被應用的具體位置。

   織入是把切面應用到目標對象並創建新的代理對象的過程。

  最關鍵的概念就是切點定義了哪些連接點會得到通知。創建切點來定義切面所織入的連接點是AOP框架的基本功能。

2.切點表達式的構成

 切面表達式,切點表達式中主要包含三個部分:通配符,運算符,指示器。

    

     

   重點是execution()

    

   匹配包:

  

  匹配對象:第三個是根據bean的id來匹配的

 

     參數匹配:

 

  註解匹配:

 

 只想攔截拋出異常的方法

 

 3.Spring AOP實例:

     先要找到應用中的連接點,即需要通知的點。

    

   編寫切面和切點表達式:

@Aspect
public class Audience {

    //定義命名的切點
    @Pointcut("execution(* *com.wx.springinaction.service.Performance.perform(..))")
    public void performance() {
    }

    @Before("performance()")
    public void silenceCellPhone() {
        System.out.println("看錶演之前,觀衆將收集調成靜音");
    }

    @Before("performance()")
    public void takeSeats() {
        System.out.println("觀衆入席坐好");
    }

    // @After  和 @AfterReturning區別:@After=@AfterReturning+@AfterThrowing
    @AfterReturning("performance()")
    public void applause() {
        System.out.println("演出結束觀衆鼓掌");
    }

    @AfterThrowing("performance()")
    public void demandRefund() {
        System.out.println("演出失敗,觀衆要求退款!!!");
    }
}

 注入切面的bean

@Configuration
@EnableAspectJAutoProxy //啓動AspectJ自動代理
@ComponentScan("com.wx.springinaction.service")
public class PerformanceConfig {
    @Bean
    public Audience audience() {
        return new Audience();
    }
}

測試:

下面繼續展示環繞通知的用法:

    @Around("performance()")
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        try {
            System.out.println("看錶演之前,觀衆將收集調成靜音");
            System.out.println("觀衆入席坐好");
            proceedingJoinPoint.proceed();
            System.out.println("演出結束觀衆鼓掌 !!");
        }catch (Throwable e){
            System.out.println("演出失敗,觀衆要求退款!!!");
        }
    }

下面繼續展示處理通知中的參數:

連接點變成:

切點變成:

切面變成:

測試:

繼續演示通過註解引入新的功能,如果一個切面能夠爲一個方法增加新的功能,爲什麼能爲一個對象增加新的功能呢?利用引入的AOP概念,切面可以爲Spring Bean增加新的方法。特別是沒有源碼控制權的時候。

要引入表演類的新方法:

新寫一個切面:加號表示接口下的所有實現。以及引入接口方法的

配置注入Bean

使用

結果:

Spring AOP的演示到此爲止,如果要更加強大的AOP,支持更多的類型那就需要AspectJ,例如當我們創建對象時候可以增加構造器通知,對象屬性的改變也可以通知等等衆多的類型。

 4.Spring AOP的原理:

  用到的設計模式兩種:代理模式,責任鏈模式,動態代理。

  首先是織入的時機,對於Spring來講,AOP織入的時機是運行期。

  

 

代理:

動態代理:java基礎--19動態代理

代理的方式有兩種,JDK和CGLib,那麼Spring AOP 選擇的是什麼代理方式呢?

Spring 是如何創建出代理的bean呢?

  如何強制使用CGlib的代理:

 然後我們再回答一個問題,多個AOP調用時如何疊加在一起的,答案是採用了責任鏈的模式

 在Spring 啓動的時候,運行期,Spring就會掃描到帶有@Aspect註解的切面類,然後根據切點的表達式匹配出所有的連接點,然後會判斷這個目標對象是接口實現還是繼承實現,然後就可以確定使用JDK還是CGLib的代理方式生成代理類。順便會判斷通知的類型,最後調用的時候當然就是調用代理類啦。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章