SpringBoot中定位切點(diǎn)的兩種常用方法
有時(shí)候,我們使用AOP來(lái)進(jìn)行放的增強(qiáng),編寫(xiě)切面類(lèi)的時(shí)候,需要定位在哪個(gè)方法上試用該切面進(jìn)行增強(qiáng),本片文章主要講解兩種在SpringBoot中定位切點(diǎn)的方法,一種是使用execution表達(dá)式的方法,一種則是利用自定義注解的方法。
接下來(lái)以一個(gè)簡(jiǎn)單的例子來(lái)講解這兩種方法的使用方式。
<==========方法執(zhí)行前==========>method();<==========方法執(zhí)行后==========>
execution 表達(dá)式execution表達(dá)式的方式主要是在定義切點(diǎn)的時(shí)候,通過(guò)表達(dá)式的方式選取到所需要增強(qiáng)的方法。
execution表達(dá)式解讀
execution(<修飾符模式>?<返回類(lèi)型模式><方法名模式>(<參數(shù)模式>)<異常模式>?)
類(lèi)型 解讀 是否必須 示例 <修飾符模式> 表示所選的修飾符類(lèi)型 否 public/private/... <返回類(lèi)型模式> 表示所選的返回值類(lèi)型 是 void/int/... <方法名模式> 表示所選的包或者方法 是 com.luke.service/com.luke.controller.*/... (<參數(shù)模式>) 表示所選方法的參數(shù) 是 *(..)/*(String name)/*(int size, ..)/... <異常模式> 表示所選方法的異常類(lèi)型 否 throws Exception/...
// 匹配指定包中的所有方法execution(* com.luke.service.*(..))// 匹配當(dāng)前包中的所有public方法execution(public * UserService.*(..))// 匹配指定包中的所有public方法,并且返回值是int類(lèi)型的方法execution(public int com.luke.service.*(..))// 匹配指定包中的所有public方法,并且第一個(gè)參數(shù)是String,返回值是int類(lèi)型的方法execution(public int com.luke.service.*(String name, ..))自定義切面類(lèi):
@Aspect@Componentpublic class LogAspect { @Pointcut('execution(* com.luke.springdata.controller.*.*(..))') public void operationLog(){} /** * 這里只定義一個(gè)Around的增強(qiáng)做展示 */ @Around('operationLog()') public Object doAround(ProceedingJoinPoint joinPoint) {Object proceed = null;try { System.out.println('方法執(zhí)行前'); proceed = joinPoint.proceed(); System.out.println('方法執(zhí)行后');} catch (Throwable throwable) { throwable.printStackTrace();}return proceed; }}
此切點(diǎn)的execution表達(dá)式為com.luke.springdata.controller包下的所有方法。使用**@Around**注解表明增強(qiáng)的方法,并且指定切點(diǎn)。
測(cè)試用Controller類(lèi)
@RestController@RequestMapping('/person')public class PersonController { @GetMapping('/test') public void test(){System.out.println('方法執(zhí)行了'); } }
運(yùn)行項(xiàng)目,調(diào)用該方法,查看結(jié)果。
方法執(zhí)行前方法執(zhí)行了方法執(zhí)行后
自定義注解的方法自定義注解的方式就是在需要增強(qiáng)的方法上面加上自定義的注解即可。
自定義注解類(lèi):
@Documented@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface Log{ }
這里自定義了一個(gè)注解Log,該注解只能加在方法上。自定義切面類(lèi):
@Aspect@Componentpublic class LogAspect { @Pointcut('@annotation(com.luke.springdata.annotation.Log)') public void operationLog(){} /** * 這里只定義一個(gè)Around的增強(qiáng)做展示 */ @Around('operationLog()') public Object doAround(ProceedingJoinPoint joinPoint) {Object proceed = null;try { System.out.println('方法執(zhí)行前'); proceed = joinPoint.proceed(); System.out.println('方法執(zhí)行后');} catch (Throwable throwable) { throwable.printStackTrace();}return proceed; }}
這里編寫(xiě)的自定義個(gè)切面類(lèi),用**@Pointcut注解定義一個(gè)切面,并且這次采用@annotation(xxx)**的方式表明如果哪個(gè)方法上添加了xxx注解,則就使用該切面做增強(qiáng)。
同時(shí)在每個(gè)增強(qiáng)的方法上使用該切面,隨后編寫(xiě)正常的方法增強(qiáng)邏輯即可。
測(cè)試用Controller類(lèi)
@RestController@RequestMapping('/person')public class PersonController { @Log @GetMapping('/test') public void test(){System.out.println('方法執(zhí)行了'); } }
此時(shí)在需要使用切面的方法上加入**@Log**注解,調(diào)用該方法,查看效果。
方法執(zhí)行前方法執(zhí)行了方法執(zhí)行后
總結(jié)兩種方式均能實(shí)現(xiàn)AOP的功能,在使用上,如果某個(gè)包下面的所有方法,都需要這個(gè)切面進(jìn)行增強(qiáng),那么使用execution表達(dá)式的方式更方便。但如果只有部分方法需要,并且分布在不同的類(lèi)中,則注解的方式更靈活。
到此這篇關(guān)于SpringBoot中定位切點(diǎn)的兩種常用方法的文章就介紹到這了,更多相關(guān)SpringBoot 定位切點(diǎn)內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 刪除docker里建立容器的操作方法2. Docker 部署 Prometheus的安裝詳細(xì)教程3. Docker 容器健康檢查機(jī)制4. IntelliJ IDEA設(shè)置自動(dòng)提示功能快捷鍵的方法5. 淺談JavaScript宏任務(wù)和微任務(wù)執(zhí)行順序6. IntelliJ IDEA刪除類(lèi)的方法步驟7. idea刪除項(xiàng)目的操作方法8. idea環(huán)境下Maven無(wú)法正常下載pom中配置的包問(wèn)題9. IntelliJ IDEA配置Tomcat服務(wù)器的方法10. Django中如何使用Channels功能

網(wǎng)公網(wǎng)安備