Spring中AOP注解@Aspect的使用詳解
AOP思想
AOP(Aspect Oriented Programming)是一種面向切面的編程思想。面向切面編程是將程序抽象成各個(gè)切面,即解剖對(duì)象的內(nèi)部,將那些影響了多個(gè)類的公共行為抽取到一個(gè)可重用模塊里,減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,增強(qiáng)代碼的可操作性和可維護(hù)性。AOP把軟件系統(tǒng)分為兩個(gè)部分:核心關(guān)注點(diǎn)和橫切關(guān)注點(diǎn)。業(yè)務(wù)處理的主要流程是核心關(guān)注點(diǎn),與之關(guān)系不大的部分是橫切關(guān)注點(diǎn)。橫切關(guān)注點(diǎn)的一個(gè)特點(diǎn)是,他們經(jīng)常發(fā)生在核心關(guān)注點(diǎn)的多處,而各處都基本相似。比如權(quán)限認(rèn)證、日志、事務(wù)處理、增強(qiáng)處理。
AOP的使用場(chǎng)景
權(quán)限認(rèn)證、日志、事務(wù)處理、增強(qiáng)處理
@Aspect的使用以及基本概念
1.切面類 @Aspect: 定義切面類,加上@Aspect、@Component注解
@Aspect @Component //設(shè)置注解執(zhí)行的順序 @Order(2) public class AnnotationAspectTest
2.切點(diǎn) @Pointcut
/** * 定義切點(diǎn),切點(diǎn)為對(duì)應(yīng)controller */ @Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))") public void aopPointCut(){ }
注:execution表達(dá)式第一個(gè)*表示匹配任意的方法返回值,第二個(gè)*表示所有controller包下的類,第三個(gè)*表示所有方法,第一個(gè)..表示任意參數(shù)個(gè)數(shù)。
3.Advice,在切入點(diǎn)上執(zhí)行的增強(qiáng)處理,主要有五個(gè)注解:
@Before 在切點(diǎn)方法之前執(zhí)行
@After 在切點(diǎn)方法之后執(zhí)行
@AfterReturning 切點(diǎn)方法返回后執(zhí)行
@AfterThrowing 切點(diǎn)方法拋異常執(zhí)行
@Around 屬于環(huán)繞增強(qiáng),能控制切點(diǎn)執(zhí)行前,執(zhí)行后
4.JoinPoint :方法中的參數(shù)JoinPoint為連接點(diǎn)對(duì)象,它可以獲取當(dāng)前切入的方法的參數(shù)、代理類等信息,因此可以記錄一些信息,驗(yàn)證一些信息等;
5.使用&&、||、!、三種運(yùn)算符來(lái)組合切點(diǎn)表達(dá)式,表示與或非的關(guān)系;
6.@annotation(annotationType) 匹配指定注解為切入點(diǎn)的方法;
具體代碼實(shí)現(xiàn)
1.AopController,用于校驗(yàn)aop是否生效:
@Controller @RequestMapping("aop") public class AopController { @RequestMapping("test") @ResponseBody public String aopTest(User user) { // System.out.println(user); System.out.println("aop測(cè)試"); return "success"; } @TestAnnotation(flag = false) @RequestMapping("aopAnnotationTest") @ResponseBody public String aopAnnotationTest(User user) { // System.out.println(user); System.out.println("aopAnnotationTest"); return "success"; } }
2.AspectTest,具體的切面類,用于添加橫切邏輯,切點(diǎn)使用execution表達(dá)式進(jìn)行匹配
@Aspect @Component //設(shè)置注解執(zhí)行的順序 @Order(1) public class AspectTest { /** * 定義切點(diǎn),切點(diǎn)為對(duì)應(yīng)controller */ @Pointcut("execution(public * com.example.zcs.Aop.controller.*.*(..))") public void aopPointCut(){ } @Before("aopPointCut()") public void testbefor(JoinPoint joinPoint) { illegalParam(joinPoint); System.out.println("執(zhí)行方法之前執(zhí)行。。。。。"); } @After("aopPointCut()") public void testAfter(JoinPoint joinPoint) { //illegalParam(joinPoint); System.out.println("執(zhí)行方法之后執(zhí)行。。。。。"); } /** *獲取請(qǐng)求參數(shù) * @param joinPoint * @return */ private static void illegalParam(JoinPoint joinPoint) { if(joinPoint == null){ return; } boolean flag = false; try{ // 參數(shù)值 Object[] args = joinPoint.getArgs(); if (args != null) { for (Object o : args) { System.out.println(o); } } }catch(Exception e){ } } }
3.AnnotationAspectTest類,具體的切面類,用于添加橫切邏輯,切點(diǎn)指定注解
@Aspect @Component //設(shè)置注解執(zhí)行的順序 @Order(2) public class AnnotationAspectTest { /** * 定義切點(diǎn),切點(diǎn)為添加了注解的方法 */ @Pointcut("@annotation(com.example.zcs.Aop.annotation.TestAnnotation)") public void aopPointCut(){ } @Around("aopPointCut()") public Object Around(ProceedingJoinPoint point) throws Throwable { System.out.println("AnnotationAspectTest Around start "); //獲取注解和注解的值 TestAnnotation annotation = getAnnotation(point); if (annotation != null) { boolean flag = annotation.flag(); System.out.println("注解flags的值:" + flag); } //獲取參數(shù) Object[] args = point.getArgs(); for (Object arg : args) { System.out.println("arg ==>" + arg); } //去調(diào)用被攔截的方法 Object proceed = point.proceed(); return proceed; } //獲取注解 public TestAnnotation getAnnotation(ProceedingJoinPoint point) { Signature signature = point.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null){ return method.getAnnotation(TestAnnotation.class); } return null; } }
4.注解類TestAnnotation
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TestAnnotation { boolean flag() default true; }
到此這篇關(guān)于Spring中AOP注解@Aspect的使用詳解的文章就介紹到這了,更多相關(guān)Spring的@Aspect注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot 中嵌入式 Servlet 容器自動(dòng)配置原理解析
這篇文章主要介紹了Spring Boot 中嵌入式 Servlet 容器自動(dòng)配置原理解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11maven的settings.xml、pom.xml配置文件使用詳解
本文詳解了Maven中的配置文件settings.xml和pom.xml,闡述了它們的作用、配置項(xiàng)以及優(yōu)先級(jí)順序,settings.xml存在于Maven安裝目錄和用戶目錄下,分別作用于全局和當(dāng)前用戶,pom.xml位于項(xiàng)目根路徑下2024-09-09關(guān)于Controller層和Service層的類報(bào)錯(cuò)問(wèn)題及解決方案
這篇文章主要介紹了關(guān)于Controller層和Service層的類報(bào)錯(cuò)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Java實(shí)現(xiàn)跨服務(wù)器上傳文件功能
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)跨服務(wù)器上傳文件功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Spring?Boot?Security認(rèn)證之Redis緩存用戶信息詳解
本文介紹了如何使用Spring Boot Security進(jìn)行認(rèn)證,并通過(guò)Redis緩存用戶信息以提高系統(tǒng)性能,通過(guò)配置RedisUserDetailsManager,我們成功地將用戶信息存儲(chǔ)到了Redis中,并在Spring Security中進(jìn)行了集成,需要的朋友可以參考下2024-01-01Java使用itext5實(shí)現(xiàn)PDF表格文檔導(dǎo)出
這篇文章主要介紹了Java使用itext5實(shí)現(xiàn)PDF表格文檔導(dǎo)出,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01解決Spring Mvc中對(duì)象綁定參數(shù)重名的問(wèn)題
最近在工作中遇到了參數(shù)綁定的一個(gè)問(wèn)題,發(fā)現(xiàn)網(wǎng)上這方面的資料較少,索性自己來(lái)總結(jié)下,下面這篇文章主要給大家介紹了關(guān)于如何解決Spring Mvc中對(duì)象綁定參數(shù)重名問(wèn)題的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-08-08