@AspectJ中關於`advice`註解的使用
阿新 • • 發佈:2018-12-12
使用@AspectJ,需要額外匯入jar包,從官網下載即可,搜尋關鍵字`aspectj download`.
說明,在有些參考書中,advice譯為`增強`,依據其效用.
@Aspect | 定義一個切面 |
@PointCut | 定義複用指示器 |
@Before | 前置通知 |
@After | 後置通知 |
@Around |
環繞通知 |
@AfterReturning | 返回通知 |
@AfterThrowing | 異常通知 |
目標物件類
package siye; import org.springframework.stereotype.Component; @Component public class TargetObj { // 測試前置通知和後置通知 public void work() { System.out.println("user_work"); } // 測試異常通知. public void throwMethod() { throw new RuntimeException(); } // 測試環繞通知. public void testAround() { System.out.println("test_around_advice"); } // 測試返回通知,和引數擷取. public int testReturn(int num) { return num; } }
測試@AspectJ註解的切面類
package siye; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component // 註冊元件. @Aspect // 切面,即切點和通知的組合. public class AspectJtoAnno { @Pointcut("execution(* *.work(..))") // 定義可重用的指示器. public void myPointCut() { } /* * 前置通知和後置通知. */ @Before("myPointCut()") public void testAnnoBefore() { System.out.println("方法即將執行----advice_before"); } @After("myPointCut()") public void testAnnoAfter() { System.out.println("方法執行完畢-----advice_after"); } /* * 環繞通知. */ @Around("execution(* *.testAround(..))") public void testAnnoAround(ProceedingJoinPoint jp) { // ProceedingJoinPoint,唯一作用,通知中,呼叫被通知的方法. // 不呼叫,該通知阻塞被通知方法的呼叫. try { System.out.println("方法開始執行----advice_around"); jp.proceed(); System.out.println("方法執行完畢----advice_around"); } catch (Throwable e) { } } /* * 異常通知. */ @AfterThrowing("execution(* *.throwMethod(..))") public void testAnnoAfterThrowing() { System.out.println("方法丟擲異常----advice_throwing"); } /* * 返回通知和引數的獲取. */ /** * 提取方法中的引數. * name binding only allowed in target, this, and args pcds * * execution和args組合使用 */ @AfterReturning("execution(* *.testReturn(int)) && args(num)") public void testAnnoAfterReturning(int num) { System.out.println("提取出來的引數值是" + num); System.out.println("方法正確執行已返回-----after_returning"); } }
上下文配置類
package siye;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class ConfigClass
{
}
測試註解類
package siye;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* advice使用的5個註解.
* org.aspectj.lang.annotation.After;
* org.aspectj.lang.annotation.AfterReturning;
* org.aspectj.lang.annotation.AfterThrowing;
* org.aspectj.lang.annotation.Around;
* org.aspectj.lang.annotation.Before;
*
* 切面使用的註解.
* org.aspectj.lang.annotation.Aspect;
*/
public class UnitTest
{
public static void main(String[] args)
{
String packName = UnitTest.class.getPackage().getName();// 反射獲取包名稱.
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
context.register(ConfigClass.class);
context.scan(packName);// 取代@ComponentScan.
context.refresh();
// System.out.println(context);
TargetObj targetObj = context.getBean(TargetObj.class);
targetObj.work();
targetObj.testAround();
targetObj.testReturn(12);
try
{
System.out.println();
targetObj.throwMethod();
} catch (Exception e)
{
}
context.close();
}
}