SpringBoot中配置AOP詳解
配置AOP
1. AOP簡介
要介紹面向切面編程(Aspect-Oriented Programming,AOP) ,需要首先考慮這樣一個場景:公司有一個人力資源管理系統(tǒng)目前已經(jīng)上線,但是系統(tǒng)運行不穩(wěn)定,有時運行得很慢,為了檢測出到底是哪個環(huán)節(jié)出問題了,開發(fā)人員想要監(jiān)控每一個方法的執(zhí)行時間,再根據(jù)這些執(zhí)行時間判斷出問題所在。當問題解決后,再把這些監(jiān)控移除掉。系統(tǒng)目前已經(jīng)運行,如果手動修改系統(tǒng)中成千上萬個方法,那么工作量未免太大,而且這些監(jiān)控方法以后還要移除掉;如果能夠在系統(tǒng)運行過程中動態(tài)添加代碼,就能很好地解決這個需求。這種在系統(tǒng)運行時動態(tài)添加代碼的方式稱為面向切面編程(AOP)。Spring框架對AOP提供了很好的支持。在AOP中,有一些常見的概念需要讀者了解。
- Joinpoint (連接點):類里面可以被增強的方法即為連接點。例如,想修改哪個方法的功能,那么該方法就是一個連接點。
- Pointcut(切入點):對Joinpoint進行攔截的定義即為切入點。例如,攔截所有以insert 開始的方法,這個定義即為切入點。
- Advice (通知):攔截到Joinpoint 之后所要做的事情就是通知。例如,上文說到的打印日志監(jiān)控。通知分為前置通知、后置通知、異常通知、最終通知和環(huán)繞通知。
- Aspect ( 切面): Pointcut 和Advice的結合。
- Target (目標對象):要增強的類稱為Target。
2. Spring Boot支持
Spring Boot 在Spring 的基礎上對AOP的配置提供了自動化配置解決方案spring-boot-starter-aop,使開發(fā)者能夠更加便捷地在Spring Boot項目中使用AOP。配置步驟如下。
首先在Spring Boot Web項目中引入spring- boot-starter-aop依賴,代碼如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
然后在org.sang.aop.service包下創(chuàng)建UserService類,代碼如下:
@Service public class UserService { public String getUserById(Integer id){ System.out.println("get..."); return "user"; } public void deleteUserById(Integer id){ System.out.println("delete..."); } }
接下來創(chuàng)建切面,代碼如下:
@Component @Aspect public class LogAspect { @Pointcut("execution(* com.example.*.*(..))") public void pc1() { } @Before(value = "pc1()") public void before(JoinPoint jp) { String name = jp.getSignature().getName(); System.out.println(name + "方法開始執(zhí)行..."); } @After(value = "pc1()") public void after(JoinPoint jp) { String name = jp.getSignature().getName(); System.out.println(name + "方法執(zhí)行結束..."); } @AfterReturning(value = "pc1()", returning = "result") public void afterReturning(JoinPoint jp, Object result) { String name = jp.getSignature().getName(); System.out.println(name + "方法返回值為: " + result); } @AfterThrowing(value = "pc1 ()", throwing = "e") public void afterThrowing(JoinPoint jp, Exception e) { String name = jp.getSignature().getName(); System.out.println(name + "方法拋異常了,異常是: " + e.getMessage()); } @Around("pc1()") public Object around(ProceedingJoinPoint pjp) throws Throwable { return pjp.proceed(); } }
代碼解釋:
- @Aspect注解表明這是一個切面類。
- 第4~6行定義的pcl方法使用了@Pointcut注解,這是一個切入點定義。execution 中的第一個 * 表示方法返回任意值,第二個 * 表示service 包下的任意類,第三個 * 表示類中的任意方法,括號中的兩個點表示方法參數(shù)任意,即這里描述的切入點為service 包下所有類中的所有方法。
- 第 8~12行定義的方法使用了@Before注解,表示這是一個前置通知,該方法在目標方法執(zhí)行之前執(zhí)行。通過JoinPoint參數(shù)可以獲取目標方法的方法名、修飾符等信息。
- 第14~18行定義的方法使用了@After注解,表示這是一個后置通知,該方法在目標方法執(zhí)行之后執(zhí)行。
- 第 20~24行定義的方法使用了@AfterReturning注解,表示這是一個返回通知,在該方法中可以獲取目標方法的返回值。@AfterReturmning 注解的returning參數(shù)是指返回值的變量名,對應方法的參數(shù)。注意,在方法參數(shù)中定義了result 的類型為Object,表示目標方法的返回值可以是任意類型,若result 參數(shù)的類型為Long,則該方法只能處理目標方法返回值為Long的情況。
- 第26~30行定義的方法使用了@AfterThrowing注解,表示這是一個異常通知,即當目標方法發(fā)生異常時,該方法會被調(diào)用,異常類型為Exception 表示所有的異常都會進入該方法中執(zhí)行,若異常類型為ArithmeticException,則表示只有目標方法拋出的ArithmeticException異常才會進入該方法中處理。
- 第32~35行定義的方法使用了@Around注解,表示這是一一個環(huán)繞通知。環(huán)繞通知是所有通知里功能最為強大的通知,可以實現(xiàn)前置通知、后置通知、異常通知以及返回通知的功能。目標方法進入環(huán)繞通知后,通過調(diào)用ProceedingJoinPoint對象的proceed方法使目標方法繼續(xù)執(zhí)行,開發(fā)者可以在此修改目標方法的執(zhí)行參數(shù)、返回值等,并且可以在此處理目標方法的異常。
配置完成后,接下來在Controller 中創(chuàng)建接口,分別調(diào)用UserService中的兩個方法,即可看到LogAspect中的代碼動態(tài)地嵌入目標方法中執(zhí)行了。UserController 類的定義如下:
@RestController public class UserController { @Autowired UserService userService; @GetMapping("/getUserById") public String getUserById(Integer id) { return userService.getUserById(id); } @GetMapping("/deleteUserById") public void deleteUserById(Integer id) { userService.deleteUserById(id); } }
當訪問/getUserById 接口時,打印日志
getUserById方法開始執(zhí)行...
get...
getUserById方法返回值為: user
getUserById方法執(zhí)行結束...
到此這篇關于SpringBoot中配置AOP詳解的文章就介紹到這了,更多相關SpringBoot配置AOP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring的@Validation和javax包下的@Valid區(qū)別以及自定義校驗注解
這篇文章主要介紹了Spring的@Validation和javax包下的@Valid區(qū)別以及自定義校驗注解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01基于SpringBoot核心原理(自動配置、事件驅動、Condition)
這篇文章主要介紹了基于SpringBoot核心原理(自動配置、事件驅動、Condition),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08JAVA實現(xiàn)JSON后端向前端傳遞數(shù)據(jù)
本篇文章主要介紹了JAVA實現(xiàn)JSON后端向前端傳遞數(shù)據(jù),這里整理了詳細的代碼,具有一定的參考價值,有需要的小伙伴可以參考下。2017-03-03intelliJ IDEA 多行選中相同內(nèi)容的快捷鍵分享
這篇文章主要介紹了intelliJ IDEA 多行選中相同內(nèi)容的快捷鍵分享,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02