Spring中的@Aspect注解使用詳解
@Aspect注解使用
AOP為Aspect Oriented Programming的縮寫(xiě),意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù).AOP是OOP的延續(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開(kāi)發(fā)的效率。
在spring AOP中業(yè)務(wù)邏輯僅僅只關(guān)注業(yè)務(wù)本身,將日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來(lái),通過(guò)對(duì)這些行為的分離,我們希望可以將它們獨(dú)立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進(jìn)而改變這些行為的時(shí)候不影響業(yè)務(wù)邏輯的代碼。
相關(guān)注解介紹:
- @Aspect:作用是把當(dāng)前類(lèi)標(biāo)識(shí)為一個(gè)切面供容器讀取
- @Pointcut:Pointcut是植入Advice的觸發(fā)條件。每個(gè)Pointcut的定義包括2部分,一是表達(dá)式,二是方法簽名。方法簽名必須是 public及void型??梢詫ointcut中的方法看作是一個(gè)被Advice引用的助記符,因?yàn)楸磉_(dá)式不直觀,因此我們可以通過(guò)方法簽名的方式為 此表達(dá)式命名。因此Pointcut中的方法只需要方法簽名,而不需要在方法體內(nèi)編寫(xiě)實(shí)際代碼。
- @Around:環(huán)繞增強(qiáng),相當(dāng)于MethodInterceptor
- @AfterReturning:后置增強(qiáng),相當(dāng)于AfterReturningAdvice,方法正常退出時(shí)執(zhí)行
- @Before:標(biāo)識(shí)一個(gè)前置增強(qiáng)方法,相當(dāng)于BeforeAdvice的功能,相似功能的還有
- @AfterThrowing:異常拋出增強(qiáng),相當(dāng)于ThrowsAdvice
- @After: final增強(qiáng),不管是拋出異?;蛘哒M顺龆紩?huì)執(zhí)行
使用pointcut代碼:
package com.aspectj.test.advice; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class AdviceTest { @Around("execution(* com.abc.service.*.many*(..))") public Object process(ProceedingJoinPoint point) throws Throwable { System.out.println("@Around:執(zhí)行目標(biāo)方法之前..."); //訪問(wèn)目標(biāo)方法的參數(shù): Object[] args = point.getArgs(); if (args != null && args.length > 0 && args[0].getClass() == String.class) { args[0] = "改變后的參數(shù)1"; } //用改變后的參數(shù)執(zhí)行目標(biāo)方法 Object returnValue = point.proceed(args); System.out.println("@Around:執(zhí)行目標(biāo)方法之后..."); System.out.println("@Around:被織入的目標(biāo)對(duì)象為:" + point.getTarget()); return "原返回值:" + returnValue + ",這是返回結(jié)果的后綴"; } @Before("execution(* com.abc.service.*.many*(..))") public void permissionCheck(JoinPoint point) { System.out.println("@Before:模擬權(quán)限檢查..."); System.out.println("@Before:目標(biāo)方法為:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@Before:參數(shù)為:" + Arrays.toString(point.getArgs())); System.out.println("@Before:被織入的目標(biāo)對(duì)象為:" + point.getTarget()); } @AfterReturning(pointcut="execution(* com.abc.service.*.many*(..))", returning="returnValue") public void log(JoinPoint point, Object returnValue) { System.out.println("@AfterReturning:模擬日志記錄功能..."); System.out.println("@AfterReturning:目標(biāo)方法為:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@AfterReturning:參數(shù)為:" + Arrays.toString(point.getArgs())); System.out.println("@AfterReturning:返回值為:" + returnValue); System.out.println("@AfterReturning:被織入的目標(biāo)對(duì)象為:" + point.getTarget()); } @After("execution(* com.abc.service.*.many*(..))") public void releaseResource(JoinPoint point) { System.out.println("@After:模擬釋放資源..."); System.out.println("@After:目標(biāo)方法為:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName()); System.out.println("@After:參數(shù)為:" + Arrays.toString(point.getArgs())); System.out.println("@After:被織入的目標(biāo)對(duì)象為:" + point.getTarget()); } }
使用annotation代碼:
//注解實(shí)體類(lèi) package com.trip.demo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface SMSAndMailSender { /*短信模板String格式化串*/ String value() default ""; String smsContent() default ""; String mailContent() default ""; /*是否激活發(fā)送功能*/ boolean isActive() default true; /*主題*/ String subject() default ""; } //切面類(lèi) @Aspect @Component("smsAndMailSenderMonitor") public class SMSAndMailSenderMonitor { private Logger logger = LoggerFactory.getLogger(SMSAndMailSenderMonitor.class); /** * 在所有標(biāo)記了@SMSAndMailSender的方法中切入 * @param joinPoint * @param result */ @AfterReturning(value="@annotation(com.trip.demo.SMSAndMailSender)", returning="result")//有注解標(biāo)記的方法,執(zhí)行該后置返回 public void afterReturning(JoinPoint joinPoint , Object result//注解標(biāo)注的方法返回值) { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); boolean active = method.getAnnotation(SMSAndMailSender.class).isActive(); if (!active) { return; } String smsContent = method.getAnnotation(SMSAndMailSender.class).smsContent(); String mailContent = method.getAnnotation(SMSAndMailSender.class).mailContent(); String subject = method.getAnnotation(SMSAndMailSender.class).subject(); } /** * 在拋出異常時(shí)使用 * @param joinPoint * @param ex */ @AfterThrowing(value="@annotation(com.trip.order.monitor.SMSAndMailSender)",throwing = "ex") public void afterThrowing(JoinPoint joinPoint, Throwable ex//注解標(biāo)注的方法拋出的異常) { MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); String subject = method.getAnnotation(SMSAndMailSender.class).subject(); } } //實(shí)體類(lèi)中使用該注解標(biāo)注方法 @Service("testService ") public class TestService { @Override @SMSAndMailSender(smsContent = "MODEL_SUBMIT_SMS", mailContent = "MODEL_SUPPLIER_EMAIL", subject = "MODEL_SUBJECT_EMAIL") public String test(String param) { return "success"; } }
注意,記得在配置文件中加上:
<aop:aspectj-autoproxy proxy-target-class="true"/>
到此這篇關(guān)于Spring中的@Aspect注解使用詳解的文章就介紹到這了,更多相關(guān)@Aspect注解使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis實(shí)現(xiàn)數(shù)據(jù)庫(kù)類(lèi)型和Java類(lèi)型的轉(zhuǎn)換
MyBatis 在處理數(shù)據(jù)庫(kù)查詢(xún)結(jié)果或傳遞參數(shù)時(shí),需要將數(shù)據(jù)庫(kù)類(lèi)型與 Java 類(lèi)型之間進(jìn)行轉(zhuǎn)換,本文就給大家介紹MyBatis如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)類(lèi)型和 Java 類(lèi)型的轉(zhuǎn)換的,需要的朋友可以參考下2024-09-09詳解Spring mvc DispatchServlet 實(shí)現(xiàn)機(jī)制
本篇文章主要介紹了詳解Spring mvc DispatchServlet 實(shí)現(xiàn)機(jī)制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09Spring Boot簡(jiǎn)介與快速搭建詳細(xì)步驟
SpringBoot其本身沒(méi)有添加什么新的技術(shù),就是整合了一些現(xiàn)有的框架,并提供了一些默認(rèn)的配置,就是這些默認(rèn)的配置,極大的提高了我們的開(kāi)發(fā)效率。這篇文章主要介紹了Spring Boot簡(jiǎn)介與快速搭建,需要的朋友可以參考下2021-05-05Java AbstractMethodError原因案例詳解
這篇文章主要介紹了Java AbstractMethodError原因案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08SpringBoot @NotBlank錯(cuò)誤的解決方案
這篇文章主要介紹了SpringBoot @NotBlank錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08