Spring| AOP之 切点(Pointcut)


一. 什么是切点?

通知定义了切面的“什么”和“何时”的话, 那么切点就定义了“何处”。 切点的定义会匹配通知所要织入的一个或多个连接点。 我们通常使用明确的方法名称, 或是利用正则表达式定义所匹配的类和方法名称来指定这些切点。 有些AOP框架允许我们创建动态的切点, 可以根据运行时的决策(比如方法的参数值) 来决定是否应用通知.
比如在使用JavaConf类来声明一个切点

/**
 * 切点表达式
 */
@Pointcut("execution(** *.perform(..)) && within(com.yveshe.aspect.usage1.*)")
public void performance() {
}

在Spring的XML配置文件中声明一个切点:

 <aop:config>
     <aop:pointcut id="pointcut" expression="execution(** com.yveshe.aspect.usage2.Performance.perform(..))"/>   <!-- 定义切点 -->
     <aop:aspect ref="aspect">   <!-- 配置切面: 通知(silenceCellPhones,cleanup)+切点(pointcut,切点表达式形式) -->
          <aop:before pointcut-ref="pointcut" method="silenceCellPhones"/>
          <aop:before pointcut-ref="pointcut" method="takeSeats"/>
          <aop:after-returning pointcut-ref="pointcut" method="applause"/>
          <aop:after-throwing  pointcut-ref="pointcut" method="demanRefund"/>
          <aop:after pointcut="execution(** com.yveshe.aspect.usage2.Performance.perform(..))" method="cleanup"/>
     </aop:aspect>
 </aop:config>

总结: 切点表达式表示原来Class需要增强的地方(比如属性字段,方法啊),但在Spring中仅支持对方法的增强


二. 切点表达式的使用?

首先我们先来看一下在Java中方法是如何定的:

 public void perform() {
     System.out.println("Performance: 演员开始演出!");

     boolean flag = true;
     if (flag) {
         throw new RuntimeException("Performance: 演出出现失误!");
     }

     System.out.println("Performance: 演出正常结束!");
 }

我们可以发现方法的定义有: 访问权限 + 返回值类型 + 方法名称 + 参数列表 + 方法体.
接下来我们再看一下切点表达式的定义
在这里插入图片描述

细心的你会发现在编写的切点表达式顺序跟定义方法的顺序类似: 返回值类型 + 方法名称 + 参数列表
先是有返回值, 方法的完全限定名(类名+方法名) + 参数列表


接下来我们来看一下切点表达式的关系操作符的例子: 这里我们需要保证通过表达式找到的方法是唯一的,否则会失效.

 /**
  * 切点表达式
  */
 @Pointcut("execution(** *.perform(..)) && within(com.yveshe.aspect.usage1.*)")
 public void performance() {
 }

我们使用了“&&”操作符把execution()和within()指示器连接在一起形成与(and) 关系(切点必须匹配所有的指示器) 。

关系操作符总结:

  • “&&”操作符来标识(and) 关系
  • “||”操作符来标识或(or) 关系
  • “!”操作符来标识非(not) 操作。

注意:
因为“&”在XML中有特殊含义, 所以在Spring的XML配置里面描述切点时, 我们可以使用and来代替“&&”。 同样, or和not可以分别用来代替“||”和“!”


三. Spring AOP所支持的AspectJ切点指示器

关于Spring AOP的AspectJ切点, 最重要的一点就是Spring仅支持AspectJ切点指示器(pointcut designator) 的一个子集,也就是说AspectJ切点指示器只有一部分在Spring中是生效有用的.
下面列出了Spring AOP所支持的AspectJ切点指示器

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

除了上表所列的指示器外, Spring还引入了一个新的bean()指示器, 它允许我们在切点表达式中使用bean的ID来标识bean。 bean() 使用bean IDbean名称作为参数来限制切点只匹配特定的bean。

@Pointcut("execution(** *.perform(..)) and bean(performance)")
public void performance() {
}

如果我们需要匹配除了performance以外的Bean则,可以使用如下表达式"execution(** *.perform(..)) and !bean(performance)"

如果我们在Spring中尝试使用除上表以外的指示器时, 将会抛出IllegalArgument-Exception异常。
注意只有execution指示器是实际执行匹配的, 而其他的指示器都是用来限制匹配的,在编写切点时候execution指示器必须存在

现在, 我们已经讲解了编写切点的基础知识, 让我们再了解一下如何编写通知和使用这些切点声明切面。


相关问题:
1.spring aop切点表达式属性的规则?
2.within()是干嘛的?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值