Spring boot中使用aop
-
導(dǎo)入pom的坐標
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
-
在application.yml中增加配置項
spring: aop: auto: true proxy-target-class: true
proxy-target-class 這個值默認是false 是標準JDK基于接口的代理將起作用 是代理接口
設(shè)置為true時 是基于累的代理(cglib庫)
被攔截的方法 該方法所在的類必須已經(jīng)注入到spring容器中
@Component
class Test {
public void test1() {
...
}
}
-
切面類
- 類上要寫明注解 @Aspect
@Aspect class myAop { @After("execution(* com.xxxx.xxxx.xxx.service.xxx.test1(..))") 注意根據(jù)配置寫接口還是寫類 類代理之后接口和類都生效 public void xxx(JoinPoint jp) throws AppException { Object[] args = jp.getArgs(); args 可以獲取到攔截的那個類的參數(shù) 和 所有你想要獲得的接口 例如代理上邊的那個類 是這樣寫 String id = ((String[])args[0])[0]; 這樣就獲得了傳入的參數(shù) } }
以上aop的最少基本步驟已經(jīng)完成。
總結(jié)一些特例
-
當(dāng)被代理的方法是內(nèi)部直接調(diào)用的時候 無法通過上邊的形式攔截,需要改被代理類的寫法 官方的意思是寫兩個類 但是可能實際情況不被允許分到兩個類里
@Component class Test { public void test2() { test1(); } public void test1() { ... } } 如以上寫法內(nèi)部調(diào)用的時候aop無法生效
解決辦法
首先在類上標記開啟動態(tài)代理 @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true) 然后調(diào)用test1的時候要這么寫 if (null != AopContext.currentProxy()) { ((xxxService)AopContext.currentProxy()).test1(id); } else { test1(id); }
-
如果用的mybait里的一些delete或者add方法襟己,如果是父類的方法徽惋,就會代理不到店量。
例如 tk.mybaits里的類繼承 我們直接使用 xxxService.delete(id) 這個delete是父類的方法 這個時候是代理不到的
解決方法 在類上邊加上target標注的更明確一點翘紊,并且需要在類里重寫下父類
@After("execution(* com.xxx.xxx.base.common.base.*.deleteById(..)) target(com.xx.xx.xx.xx.service.xxxServiceImpl)")