AOP是spring的兩個主要模塊功能之一,總結一下aop的基本用法
切面類組成
首先需要在類中用@Aspect
,說明這個類時切面類,這個類主要由兩個部分組成:@Pointcut
和Advice
@Pointcut
@Pointcut是一個註解,標註在類中的方法上,主要的作用是說明要處理那些類和那些方法。
@Pointcut 裏的參數式一個表達式,包括指示器、通配符和運算符。
指示器按功能主要包括5類:
- 匹配方法:execution()
- 匹配註解:@target() @arges() @within() @annotation()
- 匹配包或類型:within()
- 匹配對象:this() bean() target()
匹配參數:arges()
注意!! 只有匹配註解的前邊有@符號
通配符主要包含3種:
- *:任意數量的字符
- +:指定類及其子類
- ..:任意數的子包或參數
運算符也主要包括3種:
- &&:與
- ||:或
- !:非
Advice
Advice說明了要執行的時機,主要是標註的類的方法上。
Advice主要有5種註解:
- @Before:前置通知
- @After: 後置通知,方法執行完之後
- @AfterReturning: 返回通知,成功執行之後
- @AfterThrowing:異常通知,拋出異常之後
- @Around:環繞通知
用法
@Pointcut用法
在@Pointcut中execution()的應用最廣,所以主要以execution()爲例說明@Pointcut的用法
execution()的語法爲:
execution(方法修飾符(可選) 返回類型 方法名 參數 異常模式(可選))
java
@Pointcut("execution(public * com.example.aopdemo.Controller.*.*(..))")
public void excudeService(){}
這個java代碼中:
第一個*
號說明返回值爲任意類型
第二個*
號說明是任意類
第三個*
號說明的是任意方法
..
說明參數爲任意個
所以整個 @Pointcut說明處理的是com.example.aopdemo.Controller
包下所有的類以及類中所有的方法,方法參數不限的方法。
Advice用法
Advice的用法大同小異,主要的差別是執行的時機,所以,主要以@Before爲例說明用法
“`java
@Before(“excudeService()”)
public void before(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method=methodSignature.getMethod();
logger.info("-----------"+method.getName());
logger.info("---------before---------");
}
``
before
這個方法說明在
excudeService()`這個@Pointcut處理的範圍之內,所有方法運行之前先運行before函數。
完整Aspect類例子的代碼
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class AopConfig {
Logger logger = LoggerFactory.getLogger(AopConfig.class);
@Pointcut("execution(public * com.example.aopdemo.Controller.*.*(..))")
public void excudeService(){}
@Pointcut("execution(* *..find*(String)) && within(com.example..*) ")
public void matchLongArg(){}
@Before("excudeService()")
public void before(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method=methodSignature.getMethod();
logger.info("-----------"+method.getName());
logger.info("---------before---------");
}
@After("excudeService()")
public void after(JoinPoint joinPoint){
Object [] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
logger.info(String.valueOf(args[i]));
}
logger.info("---------after---------");
}
}