@Aspect 註解使用詳解

AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術.AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。java

在spring AOP中業務邏輯僅僅只關注業務自己,將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,經過對這些行爲的分離,咱們但願能夠將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。spring

相關注解介紹:編程

@Aspect:做用是把當前類標識爲一個切面供容器讀取

@Pointcut:Pointcut是植入Advice的觸發條件。每一個Pointcut的定義包括2部分,一是表達式,二是方法簽名。方法簽名必須是 public及void型。能夠將Pointcut中的方法看做是一個被Advice引用的助記符,由於表達式不直觀,所以咱們能夠經過方法簽名的方式爲 此表達式命名。所以Pointcut中的方法只須要方法簽名,而不須要在方法體內編寫實際代碼。
@Around:環繞加強,至關於MethodInterceptor
@AfterReturning:後置加強,至關於AfterReturningAdvice,方法正常退出時執行
@Before:標識一個前置加強方法,至關於BeforeAdvice的功能,類似功能的還有
@AfterThrowing:異常拋出加強,至關於ThrowsAdvice
@After: final加強,無論是拋出異常或者正常退出都會執行
使用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:執行目標方法以前...");
//訪問目標方法的參數:
Object[] args = point.getArgs();
if (args != null && args.length > 0 && args[0].getClass() == String.class) {
args[0] = "改變後的參數1";
}
//用改變後的參數執行目標方法
Object returnValue = point.proceed(args);
System.out.println("@Around:執行目標方法以後...");
System.out.println("@Around:被織入的目標對象爲:" + point.getTarget());
return "原返回值:" + returnValue + ",這是返回結果的後綴";
}

@Before("execution(* com.abc.service.*.many*(..))")
public void permissionCheck(JoinPoint point) {
System.out.println("@Before:模擬權限檢查...");
System.out.println("@Before:目標方法爲:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@Before:參數爲:" + Arrays.toString(point.getArgs()));
System.out.println("@Before:被織入的目標對象爲:" + 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:目標方法爲:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@AfterReturning:參數爲:" +
Arrays.toString(point.getArgs()));
System.out.println("@AfterReturning:返回值爲:" + returnValue);
System.out.println("@AfterReturning:被織入的目標對象爲:" + point.getTarget());

}

@After("execution(* com.abc.service.*.many*(..))")
public void releaseResource(JoinPoint point) {
System.out.println("@After:模擬釋放資源...");
System.out.println("@After:目標方法爲:" +
point.getSignature().getDeclaringTypeName() +
"." + point.getSignature().getName());
System.out.println("@After:參數爲:" + Arrays.toString(point.getArgs()));
System.out.println("@After:被織入的目標對象爲:" + point.getTarget());
}
}
使用annotation代碼:框架

//註解實體類
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 "";
/*是否激活發送功能*/
boolean isActive() default true;
/*主題*/
String subject() default "";
}



//切面類
@Aspect
@Component("smsAndMailSenderMonitor")
public class SMSAndMailSenderMonitor {

private Logger logger = LoggerFactory.getLogger(SMSAndMailSenderMonitor.class);


/**
* 在全部標記了@SMSAndMailSender的方法中切入
* @param joinPoint
* @param result
*/
@AfterReturning(value="@annotation(com.trip.demo.SMSAndMailSender)", returning="result")//有註解標記的方法,執行該後置返回
public void afterReturning(JoinPoint joinPoint , Object result//註解標註的方法返回值) {
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();

}



/**
* 在拋出異常時使用
* @param joinPoint
* @param ex
*/
@AfterThrowing(value="@annotation(com.jd.trip.hotel.ebooking.order.monitor.SMSAndMailSender)",throwing = "ex")
public void afterThrowing(JoinPoint joinPoint, Throwable ex//註解標註的方法拋出的異常) {
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
Method method = ms.getMethod();
String subject = method.getAnnotation(SMSAndMailSender.class).subject();

}

}


//實體類中使用該註解標註方法
@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";
}



注意,記得在配置文件中加上:ide

<aop:aspectj-autoproxy proxy-target-class="true"/>
————————————————
版權聲明:本文爲CSDN博主「狂豐」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/fz13768884254/article/details/83538709函數式編程

相關文章
相關標籤/搜索