AOP的本質還是動態代理對方法調用進行增強。
SpringBoot 提供了方便的注解實現自定義切面Aspect。
1、使用需要了解的幾個概念:
切面、@Aspect
切點、@Pointcut、
通知、@Before/@After/@Around/@AfterReturning/@AfterThrowing
2、Pointcut expression表達式規則
Pointcut 是指那些方法需要被執行"AOP",是由"Pointcut Expression"來描述的.
Pointcut可以有下列方式來定義或者通過通配符&& || 和!的方式進行組合.
args()、@args()
execution()
this()
target() 、@target()
within()、@within()
@annotation
舉例說明:
任意公共方法的執行:
execution(public * *(..))
任何一個以“set”開始的方法的執行:
execution(* set*(..))‘
AccountService 接口的任意方法的執行:
execution(* com.xyz.service.AccountService.*(..))
定義在service包里的任意方法的執行:
execution(* com.xyz.service.*.*(..))
定義在service包和所有子包里的任意類的任意方法的執行:
execution(* com.xyz.service..*.*(..))
定義在pointcutexp包和所有子包里的JoinPointObjP2類的任意方法的執行:
execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")
***> 最靠近(..)的為方法名,靠近.*(..))的為類名或者接口名,如上例的JoinPointObjP2.*(..))
pointcutexp包里的任意類.
within(com.test.spring.aop.pointcutexp.*)
pointcutexp包和所有子包里的任意類.
within(com.test.spring.aop.pointcutexp..*)
實現了Intf接口的所有類,如果Intf不是接口,限定Intf單個類.
this(com.test.spring.aop.pointcutexp.Intf)
***> 當一個實現了接口的類被AOP的時候,用getBean方法必須cast為接口類型,不能為該類的類型.
帶有@Transactional標注的所有類的任意方法.
@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)
帶有@Transactional標注的任意方法.
@annotation(org.springframework.transaction.annotation.Transactional)
***> @within和@target針對類的注解,@annotation是針對方法的注解
參數帶有@Transactional標注的方法.
@args(org.springframework.transaction.annotation.Transactional)
參數為String類型(運行是決定)的方法.
args(String)
這篇文章寫得不錯可參考:https://www.jianshu.com/p/fbbdebf200c9