@Aspect 注解使用詳解

AOP為Aspect Oriented Programming的縮寫卵牍,意為:面向切面編程闯团,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù).AOP是OOP的延續(xù)摩瞎,是軟件開發(fā)中的一個熱點身弊,也是Spring框架中的一個重要內(nèi)容丸边,是函數(shù)式編程的一種衍生范型儿普。利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離贮竟,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低丽焊,提高程序的可重用性,同時提高了開發(fā)的效率咕别。

在spring AOP中業(yè)務(wù)邏輯僅僅只關(guān)注業(yè)務(wù)本身技健,將日志記錄,性能統(tǒng)計惰拱,安全控制凫乖,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來弓颈,通過對這些行為的分離帽芽,我們希望可以將它們獨立到非指導業(yè)務(wù)邏輯的方法中,進而改變這些行為的時候不影響業(yè)務(wù)邏輯的代碼翔冀。

相關(guān)注解介紹:

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

@Pointcut:Pointcut是植入Advice的觸發(fā)條件导街。每個Pointcut的定義包括2部分,一是表達式纤子,二是方法簽名搬瑰。方法簽名必須是 public及void型款票。可以將Pointcut中的方法看作是一個被Advice引用的助記符泽论,因為表達式不直觀艾少,因此我們可以通過方法簽名的方式為 此表達式命名。因此Pointcut中的方法只需要方法簽名翼悴,而不需要在方法體內(nèi)編寫實際代碼缚够。
@Around:環(huán)繞增強,相當于MethodInterceptor
@AfterReturning:后置增強鹦赎,相當于AfterReturningAdvice谍椅,方法正常退出時執(zhí)行
@Before:標識一個前置增強方法,相當于BeforeAdvice的功能古话,相似功能的還有
@AfterThrowing:異常拋出增強雏吭,相當于ThrowsAdvice
@After: final增強,不管是拋出異撑悴龋或者正常退出都會執(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í)行目標方法之前...");
//訪問目標方法的參數(shù):
Object[] args = point.getArgs();
if (args != null && args.length > 0 && args[0].getClass() == String.class) {
args[0] = "改變后的參數(shù)1";
}
//用改變后的參數(shù)執(zhí)行目標方法
Object returnValue = point.proceed(args);
System.out.println("@Around:執(zhí)行目標方法之后...");
System.out.println("@Around:被織入的目標對象為:" + 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:目標方法為:" + 
            point.getSignature().getDeclaringTypeName() + 
            "." + point.getSignature().getName());
    System.out.println("@Before:參數(shù)為:" + 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:參數(shù)為:" + 
            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:參數(shù)為:" + 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 "";
/*是否激活發(fā)送功能*/
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")//有注解標記的方法,執(zhí)行該后置返回
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.trip.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";
}

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

<aop:aspectj-autoproxy proxy-target-class="true"/>

原文鏈接:https://blog.csdn.net/fz13768884254/article/details/83538709

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摘完,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子婚温,更是在濱河造成了極大的恐慌描焰,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栅螟,死亡現(xiàn)場離奇詭異荆秦,居然都是意外死亡,警方通過查閱死者的電腦和手機力图,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門步绸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吃媒,你說我怎么就攤上這事瓤介。” “怎么了赘那?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵刑桑,是天一觀的道長。 經(jīng)常有香客問我募舟,道長祠斧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任拱礁,我火速辦了婚禮琢锋,結(jié)果婚禮上辕漂,老公的妹妹穿的比我還像新娘。我一直安慰自己吴超,他們只是感情好钉嘹,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鲸阻,像睡著了一般跋涣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赘娄,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天仆潮,我揣著相機與錄音宏蛉,去河邊找鬼遣臼。 笑死,一個胖子當著我的面吹牛拾并,可吹牛的內(nèi)容都是我干的揍堰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嗅义,長吁一口氣:“原來是場噩夢啊……” “哼屏歹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起之碗,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蝙眶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后褪那,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體幽纷,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年博敬,在試婚紗的時候發(fā)現(xiàn)自己被綠了友浸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡偏窝,死狀恐怖收恢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祭往,我是刑警寧澤伦意,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站硼补,受9級特大地震影響驮肉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜括勺,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一缆八、第九天 我趴在偏房一處隱蔽的房頂上張望曲掰。 院中可真熱鬧,春花似錦奈辰、人聲如沸栏妖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吊趾。三九已至,卻和暖如春瑟啃,著一層夾襖步出監(jiān)牢的瞬間论泛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工蛹屿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屁奏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓错负,卻偏偏與公主長得像坟瓢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子犹撒,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容