詳解Spring AOP的實現(xiàn)方式
AOP基本概念
Spring框架的兩大核心:IoC和AOP
AOP:Aspect Oriented Programming(面向切面編程)
AOP是一種思想,是對某一類事情的集中處理
面向切面編程:切面就是指某一類特定的問題,所以AOP可以理解為面向特定方法編程
舉例:攔截器是AOP的一種應(yīng)用
“特定問題”:登錄校驗
針對特定問題統(tǒng)一處理:登錄校驗攔截器
Spring對AOP進行了實現(xiàn),并且提供了一些API,就是Spring AOP
AOP的作用:
攔截器作用的維度是URL(?次請求和響應(yīng)), @ControllerAdvice 應(yīng)用 場景主要是全局異常處理 (配合自定義異常效果更佳), 數(shù)據(jù)綁定, 數(shù)據(jù)預(yù)處理。 AOP作用的維度更加細(xì)致(可以根據(jù)包、類、方法名、參數(shù)等進行攔截), 能夠?qū)崿F(xiàn)更加復(fù)雜的業(yè)務(wù)邏輯。
AOP開發(fā)步驟
舉例:往之前的圖書管理系統(tǒng)中創(chuàng)建一個切面aspect,打印每個接口的耗時。
引入AOP依賴
在pom.xml文件中添加配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
編寫AOP程序
打印每個接口的耗時
@Component//交給Spring管理 @Slf4j//打印日志 @Aspect//表明改類為切面 public class TimeAspect { // @Around定義哪些是目標(biāo)方法 @Around("execution(* com.example.SpringBookaliyun.controller.*.*(..))") public Object timeCost(ProceedingJoinPoint joinPoint) throws Throwable { //ProceedingJoinPoint表示作用的目標(biāo)方法 long start=System.currentTimeMillis(); //執(zhí)行目標(biāo)方法 Object result=joinPoint.proceed(); long end=System.currentTimeMillis(); log.info(joinPoint+"消耗時間:"+(end-start)+"ms"); return result; } }
通過上面的程序, 我們也可以感受到AOP面向切面編程的?些優(yōu)勢:
• 代碼無侵入: 不修改原始的業(yè)務(wù)方法, 就可以對原始的業(yè)務(wù)方法進行功能的增強或者是功能的改變
• 減少了重復(fù)代碼
• 提高開發(fā)效率
• 維護方便
AOP詳解
1.切點:切入點 ,一組規(guī)則,通過表達式來描述
@Around("execution(* com.example.SpringBookaliyun.controller.*.*(..))")
2.連接點:目標(biāo)方法就是連接點;切點描述的方法
圖書管理系統(tǒng)中controller下的所有方法(add、delete.....)
3.通知:具體的邏輯,要做的處理
4.切面:切點+通知
通知(advice)
Spring中AOP的通知類型有以下幾種:
• @Around: 環(huán)繞通知, 此注解標(biāo)注的通知方法在目標(biāo)方法前, 后都被執(zhí)行
• @Before: 前置通知, 此注解標(biāo)注的通知方法在目標(biāo)方法前被執(zhí)行
• @After: 后置通知, 此注解標(biāo)注的通知方法在目標(biāo)方法后被執(zhí)行, 無論是否有異常都會執(zhí)行
• @AfterReturning: 返回后通知, 此注解標(biāo)注的通知方法在目標(biāo)方法后被執(zhí)行, 有異常不會執(zhí)行
• @AfterThrowing: 異常后通知, 此注解標(biāo)注的通知方法發(fā)生異常后執(zhí)行
簡單做一個測試:
測試結(jié)果:
先執(zhí)行around,再執(zhí)行before;先執(zhí)行after,再執(zhí)行around
當(dāng)添加一個異常的接口,執(zhí)行異常接口的時候,觀察控制臺的順序:
切點
@PointCut
當(dāng)有多個切面的時候,切面的執(zhí)行順序按照名稱進行排序。但觀察比較麻煩,下面介紹切面優(yōu)先級。
切面優(yōu)先級(@Order)
當(dāng)我們在?個項目中, 定義了多個切面類時, 并且這些切面類的多個切入點都匹配到了同?個目標(biāo)方法. 當(dāng)目標(biāo)方法運行的時候,運行順序不方便管理。
Spring 給我們提供了一個新的注解, 來控制這些切面通知的執(zhí)行順序:@Order
使用@Order時,數(shù)字越小,優(yōu)先級越高
切點表達式
切點表達式常見有兩種表達?式
1. execution(RR):根據(jù)方法的簽名來匹配
2. @annotation(RR) :根據(jù)注解匹配
execution表達式
execution(<訪問修飾符> <返回類型> <包名.類名.?法(?法參數(shù))> <異常>)
訪問修飾符和異??梢允÷?/p>
//切點表達式?例 //TestController 下的 public修飾, 返回類型為String ?法名為t1, ?參?法 execution(public String com.example.demo.controller.TestController.t1()) //省略訪問修飾符 execution(String com.example.demo.controller.TestController.t1()) //匹配所有返回類型 execution(* com.example.demo.controller.TestController.t1()) //匹配TestController 下的所有?參?法 execution(* com.example.demo.controller.TestController.*()) //匹配TestController 下的所有?法 execution(* com.example.demo.controller.TestController.*(..)) //匹配controller包下所有的類的所有?法 execution(* com.example.demo.controller.*.*(..)) //匹配所有包下?的TestController execution(* com..TestController.*(..)) //匹配com.example.demo包下, ?孫包下的所有類的所有?法 execution(* com.example.demo..*(..))
@annotation注解匹配
execution表達式更適用有規(guī)則的, 如果我們要匹配多個無規(guī)則的方法時, 例如:TestController中的t1() 和UserController中的u1()這兩個方法.
這個時候使用execution這種切點表達式來描述比較麻煩。
此時使用@annotation 來描述這一類的切點
實現(xiàn)步驟:
1. 編寫自定義注解
2. 使用@annotation 表達式來描述切點
3. 在連接點的方法上添加自定義注解
1. 編寫自定義注解
2. 使用@annotation 表達式來描述切點
3. 在連接點的方法上添加自定義注解
此時只有執(zhí)行h1和t2時,控制臺才會出現(xiàn)對切點的描述
到此這篇關(guān)于Spring AOP的實現(xiàn)方式的文章就介紹到這了,更多相關(guān)Spring AOP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Java實現(xiàn)一個復(fù)雜關(guān)系表達式過濾器
這篇文章主要為大家詳細(xì)介紹了如何基于Java實現(xiàn)一個復(fù)雜關(guān)系表達式過濾器。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-07-07IDEA插件之mybatisx插件使用教程(超詳細(xì)!)
MybatisX 是一款基于IDEA的快速開發(fā)插件,為效率而生,下面這篇文章主要給大家介紹了關(guān)于IDEA插件之mybatisx插件使用的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06mybatis if test 不為空字符串且不為null的問題
這篇文章主要介紹了mybatis if test 不為空字符串且不為null的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03使用springboot不自動初始化數(shù)據(jù)庫連接池
這篇文章主要介紹了使用springboot不自動初始化數(shù)據(jù)庫連接池,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09