您好,登錄后才能下訂單哦!
前言
在軟件開發中,散布于應用中多處的功能被稱為橫切關注點,通常來講,這些橫切關注點從概念上是與應用的業務邏輯相分離的。把這些橫切關注點和業務邏輯分離出來正是AOP要解決的問題。AOP能夠幫我們模塊化橫切關注點,換言之,橫切關注點可以被描述為影響應用多出的功能。這些橫切點被模塊化特殊的類,這些類被稱為切面。
術語定義
通知:切面有必須要完成的工作,在AOP中,切面的工作被稱為通知。通知定義了切面是什么以及何時使用,除了描述切面要完成的工作,通知還解決了何時執行這個工作的問題,它應該在某個方法之前?之后?之前和之后都調用?還是只在方法拋出異常時調用?
連接點:連接點是應用程序執行過程中,能夠插入切面的一個點。
切點:是在連接點的基礎上定義切點,比方說一個類由十幾個方法,每個方法的調用前和調用后都可以插入通知,但是你只想選擇幾個方法插入通知,因此你定義一個切點來選擇你想插入的通知的方法。
切面:切面就是通知和切點的結合。
織入:織入是把切面應用到目標對象并創建新的代理對象的過程,切面在指定的連接點被織入到目標對象中。在目標對象的生命周期里有多個點可以進行織入:編譯期、類加載期、運行期。其中編譯器織入需要特殊的編譯器,類加載器織入需要特殊的類加載器,spring的AOP 是在運行期織入通知的。
Spring的AOP支持
spring提供了AOP的四種支持,分別是:基于代理的經典Spring AOP模式;純POJO切面;@AspectJ注解驅動的切面;@注入式AspectJ切面。spring所創建的通知都是用標準的Java類編寫的,而且定義通知所應用的切點通常會使用注解或在Spring配置文件里采用XML來編寫。
spring只支持方法級別的連接點。
在spring AOP中,要使用AspectJ的切點表達式語言來定義切點,關于Spring AOP的AspectJ切點,最重要的一點就是Spring僅支持AspectJ切點指示器的一個子集:
1.arg() 限制連接點匹配參數為指定類型的執行方法;
2.@args() 限制連接點匹配參數由指定注解標注的執行方法;
3.execution() 用于匹配是連接點的執行方法;
4.this() 限制連接點匹配AOP代理的bean引用為指定類型的類
5.target 限制連接點匹配目標對象為指定類型的類
6.@target() 限制連接點匹配特定的執行對象,這些對象對應的類要具有指定類型的注解
7.within() 限制連接點匹配指定的類型
8.@within() 限制連接點匹配特定注解所標注的類型
9.@annotation 限定匹配帶有指定注解的連接點
spring 注解創建切面
目標對象:
package concert; public interface Performance{ public void perform(); }
切面對象:
package concert; @Aspect//表示Audience的實例是一個切面 public class Audience{ @Before("execution(**concert.Performance.perform(..))") public void silenceCellPhones(){ //在perfrom方法執行之前 } @Before("execution(**concert.Performance.perform(..))") public void takeSeats(){ //在perfrom方法執行之前 } @AfterReturning("execution(**concert.Performance.perform(..))") public void silenceCellPhones(){ //在perfrom方法執行之后 } @AfterThrowing("execution(**concert.Performance.perform(..))") public void silenceCellPhones(){ //在perfrom方法拋出異常之后 } }
上面的類中切點表達式execution(**concert.Performance.perform(..))多次出現,我們也可以通過@Pointcut注解避免每次都寫很長的切點表但是如下所示:
@Aspect//表示Audience的實例是一個切面 public class Audience{ @Pointcut("execution(**concert.Performance.perform(..))") public void performance(){} @Before("performance()") public void silenceCellPhones(){ //在perfrom方法執行之前 } @Before("performance()") public void takeSeats(){ //在perfrom方法執行之前 } @AfterReturning("performance()") public void silenceCellPhones(){ //在perfrom方法執行之后 } @AfterThrowing("performance()") public void silenceCellPhones(){ //在perfrom方法拋出異常之后 } }
接下來需要在配置文件中配置切面如下所示:
@Configuration @EnableAspectJAutoProxy//啟動AspectJ自動代理 @ComponentScan public class ConcertConfig{ } //或者在配置文件中配置中添加 <aop:aspectj-autoproxy />
表示啟動切面代理
環繞通知:
@Aspect//表示Audience的實例是一個切面 public class Audience{ @Pointcut("execution(**concert.Performance.perform(..))") public void performance(){} @Before("performance()") public void watchPerformance(ProceedingJoinPoint jp){ //在方法之前執行 System.out.println(" beform the method is invoked"); jp.proceed()//控制權交給目標方法 //在方法之后執行 System.out.println(" after the method is invoked"); } }
處理通知中的參數
public class Audience{ @Pointcut("execution(**concert.Performance.perform(int))&&args(trackNumber)") public void performance(){} @Before("performance(trackNumber)") public void watchPerformance(int trackNumber){ //截獲傳遞給目標方法的參數并傳遞給切面中處理方法 System.out.println(trackNumber); } }
xml中聲明切面
spring AOP提供的xml配置元素:
1.<aop:advisor> 定義AOP通知;
2.<aop:after> 后置通知;
3.<aop:after-returning> 返回通知
4.<aop:around> 環繞通知
5.<aop:aspect> 定義一個切面
6.<aop:aspectj-autoproxy> 啟用切面注解驅動
7.<aop:before> 前置通知
8.<aop:config> 頂層的AOP配置元素;
9.<aop:pointcut>:定義個切點
<aop:config> <aop:aspect ref="audience"> <aop:before pointcut="execution(**concert.Performance.perform())" method="silenceCellPhones"/> <aop:before pointcut="execution(**concert.Performance.perform())" method="takeSeats"/> <aop:after-returning pointcut="execution(**concert.Performance.perform())" method="applause"/> <aop:after-throwing pointcut="execution(**concert.Performance.perform())" method="demandRefund"/> </aop:aspect> </aop config>
定義切點:
<aop:config> <aop:aspect ref="audience"> <aop:pointcut id="performance" expression="execution(**concert.Performance.perform())"> <aop:before pointcut-ref="performance" method="silenceCellPhones"/> <aop:before pointcut="performance" method="takeSeats"/> <aop:after-returning pointcut="performance" method="applause"/> <aop:after-throwing pointcut="performance" method="demandRefund"/> </aop:aspect> </aop config>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。