天天看點

SpringFramework核心技術五:面向切面程式設計(AOP)和Spring

面向對象和面向切面兩種程式設計方式的比較

面向方面程式設計(AOP)通過提供關于程式結構的另一種思考方式來補充面向對象程式設計(OOP)。OOP中子產品化的關鍵單元是類,而在AOP中,子產品化的單元是方面。方面可以實作關注的子產品化,例如跨越多種類型和對象的事務管理。(這種擔憂在AOP文獻中常常被稱為橫切關注點。)

AOP的介紹

1.基本的介紹

AOP架構是Spring的關鍵元件之一。雖然Spring IoC容器不依賴AOP,也就是說如果你不想使用AOP那麼就不用AOP,AOP可以為Spring IoC提供功能非常強大的中間件解決方案。

Spring 2.0+ AOP

Spring 2.0引入了一種使用基于模式的方法或@AspectJ注釋樣式編寫自定義方面的更簡單,更強大的方法。這兩種風格都提供完全類型化的建議和AspectJ切入點語言的使用,同時仍然使用Spring AOP進行編織。

本章将讨論基于Spring 2.0+模式和@AspectJ的AOP支援。下一章将讨論較低級别的AOP支援,如Spring 1.2應用程式中常見的那樣。

AOP在Spring架構中用于……

  • …提供聲明式企業服務,特别是作為EJB聲明式服務的替代品。最重要的這種服務是 聲明式事務管理。
  • …允許使用者實作自定義方面,補充他們與AOP一起使用OOP。

2.AOP概念

AOP的概念

3.Spring架構的核心

Spring架構的核心原則之一是非侵入性 ; 這是因為您不應該被迫在您的業務/域模型中引入特定于架構的類和接口。但是,在某些地方,Spring Framework确實為您提供了将Spring Framework特定的依賴項引入代碼庫的選項:為您提供此類選項的基本原理是因為在某些情況下,它可能更容易閱讀或編寫某些特定的部分功能以這種方式。Spring Framework(幾乎)總是為您提供選擇:您可以自由決定哪種選項最适合您的特定用例或場景。

與本章相關的一個選擇是選擇哪種AOP架構(以及哪種AOP樣式)。您可以選擇AspectJ和/或Spring AOP,并且您還可以選擇@AspectJ批注樣式方法或Spring XML配置樣式方法。本章選擇首先引入@AspectJ風格方法的事實不應視為Spring團隊贊成Spring XML配置風格的@AspectJ注釋風格方法。

4.AOP代理

Spring AOP預設使用AOP代理的标準JDK 動态代理。這使得任何接口(或接口集)都可以被代理。

Spring AOP也可以使用CGLIB代理。這是代理類而不是接口所必需的。如果業務對象不實作接口,則預設使用CGLIB。因為優良的做法是程式設計接口而不是類; 業務類通常會實作一個或多個業務接口。在需要通知未在接口中聲明的方法的情況下,或者需要将代理對象作為具體類型傳遞給方法的情況下(希望很少),可以 強制使用CGLIB。

掌握Spring AOP是基于代理的事實是很重要的。請參閱 了解AOP代理以徹底檢查此實作細節的實際含義。

二、@AspectJ支援

5.2。@AspectJ支援

@AspectJ引用了一種将方面聲明為正常Java類的注釋類型。AspectJ項目引入了@AspectJ風格, 作為AspectJ 5版本的一部分。Spring使用AspectJ提供的用于切入點解析和比對的庫來解釋與AspectJ 5相同的注釋。AOP運作時仍然是純粹的Spring AOP,并且不依賴于AspectJ編譯器或編織器。

1.啟用@AspectJ支援

要在Spring配置需要啟用配置基于

@AspectJ

方面的Spring AOP和Spring支援使用@AspectJ切面,自動代理基于它們是否被那些方面建議豆。通過autoproxying我們的意思是,如果Spring确定一個或多個方面的bean被建議,它會自動生成該bean的代理來攔截方法調用并確定根據需要執行通知。

可以使用XML或Java風格配置啟用@AspectJ支援。無論哪種情況,您還需要確定AspectJ的aspectjweaver.jar庫位于應用程式的類路徑中(版本1.8或更高版本)。該庫可在’lib’AspectJ發行版的 目錄中或通過Maven Central存儲庫獲得。

2.啟用@AspectJ支援

要使用Java啟用@AspectJ支援,請@Configuration添加@EnableAspectJAutoProxy 注釋:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}           

使用XML配置啟用@AspectJ支援

要使用基于XML的配置啟用@AspectJ支援,請使用以下aop:aspectj-autoproxy 元素:

<aop:aspectj-autoproxy/>           

3.Declaring(宣布) an aspect(切面)

啟用@AspectJ支援後,任何在應用程式上下文中定義的,具有@AspectJ方面(具有@Aspect注解)的類的bean 都将被Spring自動檢測并用于配置Spring AOP。以下示例顯示了一個不太有用的方面所需的最小定義:

應用程式上下文中的正常bean定義,指向具有@Aspect注釋的bean類:

<bean id="myAspect" class="org.xyz.NotVeryUsefulAspect">
    <!-- configure properties of aspect here as normal -->
</bean>           

而NotVeryUsefulAspect類的定義,與注解 org.aspectj.lang.annotation.Aspect注釋;

package org.xyz;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class NotVeryUsefulAspect {

}           

方面(帶有注釋的類@Aspect)可能具有與任何其他類一樣的方法和字段。它們也可能包含切入點,建議和介紹(類型間)聲明。

通過元件掃描自動檢測方面

您可以在Spring XML配置中将方面類注冊為正常bean,或者通過類路徑掃描自動檢測它們 - 就像任何其他Spring管理的bean一樣。但是,請注意,@Aspect注解是不足夠的classpath中自動檢測:為了這個目的,你需要添加一個單獨的@Component注釋(或可選擇地有資格,按照Spring的元件掃描器的規則自定義構造型注解)。

與其他方面的方面建議?

在Spring AOP,它是不是可以有自己的方面從其他方面意見的目标。類上的@Aspect注釋将其标記為方面,是以将其從自動代理中排除。

4.Declaring a pointcut(切入點)

回想一下,切入點确定了感興趣的連接配接點,進而使我們能夠控制建議何時執行。Spring AOP僅支援Spring bean的方法執行連接配接點,是以您可以将切入點視為比對Spring Bean上方法的執行。切入點聲明包含兩部分:包含名稱和任何參數的簽名以及确切地确定我們感興趣的方法執行的切入點表達式。在AOP的@AspectJ注釋樣式中,切入點簽名由正常方法提供定義,并且使用@Pointcut注釋來訓示切入點表達式(用作切入點簽名的方法 必須具有void傳回類型)。

一個例子将幫助區分切入點簽名和切入點表達式之間的差別。以下示例定義了一個名為的切入點’anyOldTransfer’,它将比對任何名為的方法的執行’transfer’:

@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature           

……

三、Spring AOP還是完整的AspectJ?

使用最簡單的方法。Spring AOP比使用完整的AspectJ更簡單,因為不需要将AspectJ編譯器/編織器引入到開發和建構過程中。如果您隻需要建議Spring bean執行操作,那麼Spring AOP就是正确的選擇。如果您需要建議不是由Spring容器管理的對象(通常是域對象),那麼您将需要使用AspectJ。如果您希望建議除簡單方法執行之外的連接配接點(例如,字段擷取或設定連接配接點等),則還需要使用AspectJ。

使用AspectJ時,您可以選擇AspectJ語言文法(也稱為“代碼樣式”)或@AspectJ注釋樣式。很顯然,如果你不使用Java 5+,那麼你已經選擇了…使用代碼風格。如果方面在您的設計中扮演重要角色,并且您可以使用針對Eclipse 的AspectJ開發工具(AJDT)插件,那麼AspectJ語言文法是首選選項:它更幹淨更簡單,因為語言是專門為寫方面。如果您沒有使用Eclipse,或者隻有少數幾個方面在應用程式中不起主要作用,那麼您可能需要考慮使用@AspectJ風格,并在IDE中使用正常的Java編譯,并添加一個方面編織階段到您的建構腳本。

這個面向切面程式設計講的較為抽象!

具體的下一次咱們在研究下!

繼續閱讀