Spring对AOP的支持
Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理,故AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。
Spring创建代理的规则为:
1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB
AOP编程时,我们只需要参与到三个部分:
1、定义普通业务组件
2、定义切入点,一个切入点可能横切多个业务组件
3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作
即:代理对象的方法=增强处理+被代理对象
Spring AOP支持以下AspectJ切入点指示符(PCD)用于切入点表达式:
- execution:用于匹配方法执行连接点。这是使用Spring AOP时使用的主要切入点指示符。
-
within:限制匹配某些类型中的连接点(使用Spring AOP时在匹配类型中声明的方法的执行)。
-
this:限制与连接点的匹配(使用Spring AOP时执行方法),其中bean引用(Spring AOP代理)是给定类型的实例。
-
target:限制匹配连接点(使用Spring AOP时执行方法),其中目标对象(被代理的应用程序对象)是给定类型的实例。
-
args:限制与连接点的匹配(使用Spring AOP时执行方法),其中参数是给定类型的实例。
-
@target:限制与连接点的匹配(使用Spring AOP时执行方法),其中执行对象的类具有给定类型的注释。
-
@args:限制与连接点的匹配(使用Spring AOP时执行方法),其中传递的实际参数的运行时类型具有给定类型的注释。
-
@within:限制匹配到具有给定注释的类型中的连接点(使用Spring AOP时执行在具有给定注释的类型中声明的方法)。
-
@annotation:限制连接点的匹配,其中连接点的主题(在Spring AOP中执行的方法)具有给定的注释。
结合Pointcut表达式
组合切入点表达式,可以使用&&,
||
和组合!
。您还可以按名称引用切入点表达式,下面是三个切入点表达式:
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}
@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {}
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}
①anyPublicOperation
如果方法执行连接点表示任何公共方法的执行,则匹配
②inTrading
如果方法执行在交易模块中,则匹配
③tradingOperation
如果方法执行表示交易模块中的任何公共方法,则匹配
常见的切入点表达式
1.执行任何公共方法:
execution(public * *(..))
2.执行名称以以下开头的任何方法set
:
execution(* set*(..))
3.执行AccountService
接口定义的任何方法:
execution(* com.xyz.service.AccountService.*(..))
4.执行service
包中定义的任何方法:
execution(* com.xyz.service.*.*(..))
5.执行服务包或其子包中定义的任何方法:
execution(* com.xyz.service..*.*(..))
6.服务包中的任何连接点(仅在Spring AOP中执行方法):
within(com.xyz.service.*)
7.服务包或其子包中的任何连接点(仅在Spring AOP中执行方法):
within(com.xyz.service..*)
8.代理实现AccountService
接口的任何连接点(仅在Spring AOP中执行方法) :
this(com.xyz.service.AccountService)
9.目标对象实现AccountService
接口的任何连接点(仅在Spring AOP中执行方法):
target(com.xyz.service.AccountService)
10.采用单个参数的任何连接点(仅在Spring AOP中执行方法)以及在运行时传递的参数是Serializable
:
args(java.io.Serializable)
11.目标对象具有@Transactional
注释的任何连接点(仅在Spring AOP中执行方法) :
@target(org.springframework.transaction.annotation.Transactional)
12.任何连接点(仅在Spring AOP中执行的方法),其中目标对象的声明类型具有@Transactional
注释:
@within(org.springframework.transaction.annotation.Transactional)
13.任何连接点(仅在Spring AOP中执行方法),其中执行方法具有 @Transactional
注释:
@annotation(org.springframework.transaction.annotation.Transactional)
14.任何连接点(仅在Spring AOP中执行的方法),它接受一个参数,并且传递的参数的运行时类型具有@Classified
注释:
@args(com.xyz.security.Classified)
15.名为的Spring bean上的任何连接点(仅在Spring AOP中执行方法) tradeService
:
bean(tradeService)
16.具有与通配符表达式匹配的名称的Spring bean上的任何连接点(仅在Spring AOP中执行方法)*Service
:
bean(*Service)
AspectJ指示符
现有的指示符自然分为三组:kinded,scoping和contextual:
-
Kinded代号选择特定类型的连接点的:
execution
,get
,set
,call
,和handler
。 -
范围界定指示符选择一组感兴趣的连接点(可能是多种类型):
within
和withincode
-
基于上下文语境指示符匹配(和任选的绑定): ,
this
,target
和@annotation