一、AOP底層原理實現
- 假如目標對象(被代理對象)實現接口,則底層默認採用JDK動態代理機制爲目標對象創建代理對象(目標類和代理類會實現共同接口)
- 假如目標對象(被代理對象)沒有實現接口,則底層默認採用CGLIB代理機制爲目標對象創建代理對象(默認創建的代理類會繼承目標對象類型)
二、maven 項目添加依賴
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
三、配置AOP實現
spring配置:
<!-- 啓用AOP註解(自動爲目標對象創建代理對象) -->
<aop:aspectj-autoproxy/>
或
配置類上使用@EnableAspectJAutoProxy
四、類型通知(Advice)
在AOP編程中有五種類型的通知:
- 前置通知 (@Before) 方法執行之前執行
- 返回通知 (@AfterReturning) 方法return之後執行
- 異常通知 (@AfterThrowing) 方法出現異常之後執行
- 後置通知 (@After) : 又稱爲最終通知(finally)
- 環繞通知 (@Around) :以上四個一起使用時可以直接使用@Around通知替換
結構如下:
Try{
@Before
核心業務
@AfterReturning
}catch(Exception e){
….
@AfterThrowing
}finally{
….
@After
}
五、切面表達式
指示符 |
作用 |
bean |
用於匹配指定bean id的的方法執行 |
within
|
用於匹配指定包名下類型內的方法執行 |
@annotation |
用於匹配指定註解修飾的方法執行 |
execution |
用於進行細粒度方法匹配執行具體業務 |
bean應用於類級別,實現粗粒度的控制:
bean(userServiceImpl) |
指定一個類 |
bean(*ServiceImpl) |
指定所有的後綴爲serviceImpl的類 |
within(aop.service.UserServiceImpl) |
指定類,只能指定一個類 |
within(aop.service.*) |
只包括當前目錄下的類 |
within(aop.service..*) |
指定當前目錄包含所有子目錄中的類 |
execution方法級別,實現細粒度的控制:
語法:execution(返回值類型 包名.類名.方法名(參數列表))
execution(void aop.UserServiceImpl.addUser()) |
匹配方法 |
execution(void aop.UserServiceImpl.addUser(String)) |
方法參數必須爲字符串 |
execution(* aop..*.*(..)) |
萬能配置 |
@annotaion應用於方法級別,實現細粒度的控制:
@annotation(com.anno.CheckLog) |
指定註解全路徑,在需要應用的的方法上加上註解@CheckLog |
六、多個切面作用於同一方法
可在切面上加上@Order(1) @Order(2) @Order(n)...優先執行@Order(1)的切面
七、實例說明
@Order(1)
@Aspect
@Service
public class TestAspect {
@Pointcut("bean(UserServiceImpl)")
// @Pointcut("within(com.*)")
// @Pointcut("execution(* com..*.*(..))")
// @Pointcut("@annotation(com.anno.CheckLog)")
public void doAspect() {}
@Before("doAspect()")
public void before() {
System.out.println("@Before");
}
@After("doAspect()")
public void after() {
System.out.println("@After");
}
@AfterReturning("doAspect()")
public void afterReturning() {
System.out.println("@AfterReturning");
}
@AfterThrowing("doAspect()")
public void afterThrowing() {
System.out.println("@AfterThrowing");
}
@Around("doAspect()")
public Object around(ProceedingJoinPoint joinPoint)
throws Throwable{
try{
System.out.println("@Around before");
Object result = joinPoint.proceed();
System.out.println("@AfterReturning");
return result;
}catch(Exception e){
System.out.println("@AfterThrowing");
throw e;
}finally{
System.out.println("@After");
}
}
}