Spring AOP

一、Spring对AOP的支持

1. AOP术语

通知(Advice)
Spring切面可以应用5种类型的通知:

  • 前置通知(Before)
  • 后置通知(After)
  • 返回通知(After-returning)
  • 异常通知(After-throwing)
  • 环绕通知(Around)
    连接点(Join point)
    切点(Pointcut)
    切面(Aspect)
    引入(Introduction)
    织入(Weaving)
    在目标对象的生命周期里有多个点可以进行织入:
    • 编译期,AspectJ的织入编译器就是用这种方式
    • 类加载期
    • 运行期,Spring AOP使用此种方式织入切面。

Spring提供了4种类型的AOP支持:

  • 基于代理的经典Spring AOP
  • 纯POJO切面
  • @AspectJ注解驱动的切面
  • 注入式AspectJ切面

Spring只支持方法级别的连接点,不支持字段和构造器接入点。

2、通过切点选择连接点

Spring AOP使用AspectJ的切点表达式语言来定义切点,只支持AspectJ切点指示器的一个子集。下表为支持的指示器:

AspectJ指示器描述
args()限制连接点匹配参数为指定类型的执行方法
@args()限制连接点匹配参数由指定注解标注的执行方法
execution()用于匹配是连接点的执行方法
this()限制连接点匹配AOP代理的bean引用为指定类型的类
target限制连接点匹配目标对象为指定类型的类】
@target()限制连接点匹配特定的执行对象,这些对象对应的类型要具有指定类型的注解
within()限制连接点匹配指定的类型
@within()限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里)
@annotation限定匹配带有指定注解的连接点

编写切点
execution(* concert.Performance.perform(..))

* 号表示方法返回值可以是任意类型,然后指定全限定类名和方法名,方法参数列表(..)表明切点要选择任意的perform()方法,无论方法的入参是什么。

execution(* concert.Performance.perform(..)) && within(concert.*)

&&操作符表示同时满足的条件,也可使用||,!操作符 ,within(concert.*)表示当concert包下的任意类的方法被调用时。
xml配置中"&"有特殊含义,可以用andornot代替。

处理通知中的参数

@Pointcut("@execution(* concert.Performance.perform(int) && args(num))")
public void played(int num){}

@Befor("played(num)")
public void countPlayed(int num){
	···
}

agrs(num)表明传递给perform()方法的in类型参数也会传递到通知中去,参数名称与切点方法签名中一致。

开启配置
使用@EnableAspectJAutoProxy启动AspectJ自动代理,配置才能生效
xml使用aop命名空间<aop:aspectj-autoproxy>

通过注解引入新功能

@Aspect
public class EncoreableINtroducer(){
	@DeclareParents(value="concert.Performance+",defaultImpl=DefaultEncoreable.class)
	public static Encoreable encoreable;
}

EncoreableINtroducer 是一个切面,通过 DeclareParents 注解,将 Encoreable 接口引入到Perfirmance bean中。DeclareParents 由三部分组成:

  • value 指定哪种类型的bean需要引入该接口,Performance+中的+表示所有子类型,而不是其本身。
  • defaultImpl 指定为引入功能提供实现的类。
  • @DeclareParents注解所标注的静态属性指明了要引入的接口。

xml中声明切面
Spring aop配置元素能够以非入侵方式声明切面

AOP配置元素用途
<aop:adviser>定义aop通知器
<aop:after>定义后置通知(不管被通知的方法是否执行成功)
<aop:after-returning>定义aop返回通知
<aop:after-throwing>定义aop异常通知
<aop:around>定义aop环绕通知
<aop:aspect>定义一个切面
<aop:aspect-autoproxy>启用@AspectJ注解驱动的切面
<aop:before>定义aop前置通知
<aop:config>顶层的AOP元素。大多<aop:*>元素必须包含在<aop:config>内
<aop:declare-parents>以透明的方式为被通知的对象引入额外的接口
<aop:pointcut>定义一个切点

声明一个没有注解的bean为切面

<aop:config>
    <!--引用一个bean声明为切面-->
	<aop:aspect ref="audience">
	<aop:before pointcut="execution(* concert.Performance.perform(..))" method="dobefore" />
</aop:config>

使用<aop:pointcut>定义命名切点

<aop:config>
    <!--引用一个bean声明为切面-->
	<aop:aspect ref="audience">
	<!--定义切点-->
	<aop:pointcut id="performance" expression="execution(* concert.Performance.perform(..))">
	<aop:before pointcut-ref="performance" method="dobefore" />
</aop:config>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值