切面(AOP)相关注解
Spring支持AspectJ的注解式切面编程。
@Aspect 声明一个切面(类上)
使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。
@After 在方法执行之后执行(方法上)
@Before 在方法执行之前执行(方法上)
@Around 在方法执行之前与之后执行(方法上)
@PointCut 声明切点
在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持(类上)
@Pointcut注解表达式 @target、@annotation、@within、this、target、within等
//@Around("@annotation(自定义注解)")//自定义注解标注在方法上的方法执行aop方法
如:@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
//@Around("@within(自定义注解)")//自定义注解标注在的类上;该类的所有方法(不包含子类方法)执行aop方法
如:@Around("@within(org.springframework.transaction.annotation.Transactional)")
//@Around("within(包名前缀.*)")//com.aop.within包下所有类的所有的方法都会执行(不包含子包) aop方法
如:@Around("within(com.aop.test.*)")
//@Around("within(包名前缀..*)")//com.aop.within包下所有的方法都会执行(包含子包)aop 方法
如:@Around("within(com.aop.test..*)")
//@Around("this(java类或接口)")//实现了该接口的类、继承该类、该类本身的类---的所有方法(包括不是接口定义的方法,但不包含父类的方法)都会执行aop方法
如:@Around("this(com.aop.service.TestService)")
//@Around("target(java类或接口)")//实现了该接口的类、继承该类、该类本身的类---的所有方法(包括不是接口定义的方法,包含父类的方法)
如:@Around("target(com.aop.service.TestService)")
//@Around("@target(自定义注解)")
简介
在Spring AOP概述中我们重点注意的是AOP的整体流程和Advice,简化了一些其他的东西,其中就有一些对灵活应用Spring AOP很重要的知识点,例如Pointcut表达式,下面就介绍一下Spring AOP的Pointcut表达式。
如果你对Pointcut表达式的作用还不是很了解,可以先看一下Spring AOP概述,也可以先了解一下匹配规则,后面会有一些具体的例子来帮助理解。
我们使用最多的就是execution表示了,下面就从execution表达式开始介绍吧。
注意:把designators翻译为表达式也许不太合适,所以不必纠结这个问题,只需要知道在看到Spring AOP中的designators知道对应的是个什么东西就可以了。管它是表达式还是指示器只是一个代称而已。
execution表达式
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
上面的就是execution表达式的格式,execution匹配的就是连接点(Joinpoint,一般是方法),看上面的表达式execution是固定的,方法的修饰符是可选的,返回类型是必须的,定义的全限类型也是可选的,名称是必须的,参数是必须的,这些都可以使用通配符。
任何的public方法
execution(public * *(..))
以set开始的方法
execution(* set*(..))
定义在cn.freemethod.business.pack.Say接口中的方法
execution(* cn.freemethod.business.pack.Say.*(..))
任何cn.freemethod.business包中的方法
execution(* cn.freemethod.business.*.*(..))
任何定义在com.xyz.service包或者其子包中的方法
execution(* cn.freemethod.business..*.*(..))
其他表达式
任何在com.xyz.service包中的方法
within(com.xyz.service.*)
任何定义在com.xyz.service包或者其子包中的方法
within(com.xyz.service..*)
任何实现了com.xyz.service.AccountService接口中的方法
this(com.xyz.service.AccountService)
任何目标对象实现了com.xyz.service.AccountService的方法
target(com.xyz.service.AccountService)
一般情况下代理类(Proxy)和目标类(Target)都实现了相同的接口,所以上面的2个基本是等效的。
有且只有一个Serializable参数的方法
args(java.io.Serializable)
只要这个参数实现了java.io.Serializable接口就可以,不管是java.io.Serializable还是Integer,还是String都可以。
目标(target)使用了@Transactional注解的方法
@target(org.springframework.transaction.annotation.Transactional)
目标类(target)如果有Transactional注解的所有方法
@within(org.springframework.transaction.annotation.Transactional)
任何方法有Transactional注解的方法
@annotation(org.springframework.transaction.annotation.Transactional)
有且仅有一个参数并且参数上类型上有Transactional注解
@args(org.springframework.transaction.annotation.Transactional)
注意是参数类型上有Transactional注解,而不是方法的参数上有注解。
bean的名字为tradeService中的方法
bean(simpleSay)
bean名字为simpleSay中的所有方法。
bean名字能匹配
bean(*Impl)
bean名字匹配*Impl的bean中的所有方法。