spring05

一,  @Autowired方法, 參數, 構造方法都可載入, 跟進源碼看看

 

 

 

A>放到方法上的測試步驟:

    新建Moon.java

 

 

 

 

   新建Sun.java

 

 

 

setMoon()方法使用的參數,自定義類型的值從IOC容器中獲取, 方法里的moon會從容器中拿到

 

以下是驗證方式

在配置類要加入掃描bean包

 

 

 

測試:

  新建test02()測試方法

結果如下:(為同一個bean)

結果如下:(為同一個bean)

 

 

 

 

 

方法使用的參數,自定義類型的值從IOC容器中獲取, 方法里的moon會從容器中拿到

 

 

B> 將Autowired標記在有參構造器

 

 

 

構造函數的moon是從容器里拿到的

執行test02()測試;

 

同樣,也可以放在構造器的參數位置也可以獲取到IOC容器的bean.

 

 

 

結論: 不管@Autowired是放到參數, 方法還是構造方法, 都是從容器里取到的bean...

 

二 自動裝配:Aware注入spring底層組件原理

 

 自定義組件想要使用Spring容器底層的組件(ApplicationContext, BeanFactory, ......)

 

    思路: 自定義組件實現xxxAware, 在創建對象的時候, 會調用介面規定的方法注入到相關組件:Aware

 

    之前講過Plane.java就是使用這個

 

 

 

CTRL+SHIFT+T  找到Aware

 

 

 

查看有哪些介面繼承了Aware介面

 

 

 

使用ApplicationContextAware介面為例, 實現介面

步驟:

1, 新建Light.java類, 實現ApplicaitonContextAware介面

 

 

 

 2,實現BeanNameAware介面

 

 

 

 2,實現EmbeddedValueResolverAware介面

 

 

 

3, 將Light類加入@Component, 聲明為被掃描的組件

 

 

 

4,將test02()加入列印anno容器, 用來比如

 

 

 

5,測試, 執行test()02;

 

 

 

總結:把Spring底層的組件可以注入到自定義的bean中,ApplicationContextAware是利用ApplicationContextAwareProcessor來處理的, 其它XXXAware也類似, 都有相關的Processor來處理, 其實就是後置處理器來處理;

XXXAware---->功能使用了XXXProcessor來處理的, 這就是後置處理器的作用;

   ApplicaitonContextAware--->ApplicationContextProcessor後置處理器來處理的

 

問題: Spring怎麼把applicationContext容器注入進來的呢????

    debug棧分析, 之前講過的.

 

三 CAP27  AOP功能測試

AOP: 面向切面編程[底層就是動態代理]

指程式在運行期間動態的將某段程式碼切入到指定方法位置進行運行的編程方式

 

1,先建立MainConfigOfAOP配置類

 

 

 

 

2,在POM.XML中導入spring-aspects依賴包

 

 

 

3,新建立一個業務邏輯類Calculator.java

 

 

 

在div()方法運行之前, 記錄一下日誌, 運行後也記錄一下,運行出異常,也列印一下

有的同學可能會這麼做, 在每個方法加入個列印.

 

 

 

但這樣會有問題, 這種方式耦合了....

新建一個日誌切面類....

 

 

 

 

日誌切面類的方法需要動態感知到div()方法運行到哪裡了, 然後再執行, 如果除法開始, 就日誌開始方法,

   也叫通知方法, 分以下幾種:

      前置通知: logStart(),在目標方法(div)運行之前運行 (@Before)

      後置通知:logEnd(), 在目標方法(div)運行結束之後運行,無論正常或異常結束 (@After)

      返回通知:logReturn, 在目標方法(div)正常返回之後運行 (@AfterReturning)

      異常通知:logException, 在目標方法(div)出現異常後運行(@AfterThrowing)

      環繞通知:以上沒寫,動態代理, 手動執行目標方法運行joinPoint.procced(),最底層通知,手動指定執行目標方法(@Around), 執行之前相當於前置通知, 執行之後相當於返回通知

其實就是通過反射執行目標對象的連接點處的方法;

 

給日誌切面類LogAspect的方法標註何時運行(即通知註解)

怎麼加入 呢?

 

 

 

若不想區分切入了哪個方法及參數類型和個數,可以有如下指定方式:

 

 

 

不難發現問題:註解里的內容是冗餘重複的, 公共的程式碼應該抽出來

 

 

 

並加上Around環繞通知

 

 

 

那麼應該寫一個公共切入點表達式.

 

 

 

公共切入方法加要指定的方法

 

 

 

有了以上操作, 我們還需要將切面類和被切面的類, 都加入到容器中

 

 

 

但這個時候還會有問題, Spring無法區別以上的兩個bean哪個是切面類, 哪個是業務邏輯類

怎麼區別呢????

只需要給切面類LogAspects上加一個註解@Aspect即可.

 

 

 

是不是就完了呢?並沒有

需要開啟基於註解的AOP模式

給配置類中加@EnableAspectJAutoProxy[一定得加上,關鍵]

注意: 在spring以後會有很多@EnableXXXX, 表示開啟某項功能, 取代XML配置

 

 

 

測試: 新建一個測試類Cap10Test.java

同學們在測試的過程中, 應該怎麼測? 很容易出問題.

大家可能會這麼寫:

 

 

 

沒用到容器, 肯定是不行的, 獲取bean時使用IOC容器取出bean

 

 

 運行結果如下: