目录
1、概述
在前面介绍各类增强时,大家可能没有注意到一个问题:增强被织入到目标类的所有方法中。假设我们希望有选择地织入到目标类某些特定的方法中,就需要使用切点进行目标连接点的定位了。描述连接点是进行AOP编程最主要的一项工作。增强提供了连接点方位信息:如织入到方法前面、后面等,而切点进一步描述织入到哪些类的哪些方法上。
Spring通过org.springframework.aop.Pointcut接口描述切点,Pointcut由ClassFilter和MethodMatcher构成。它通过ClassFilter定位到某些特定类上,通过MethodMatcher定位到某些特定方法上,这样Pointcut就拥有了描述某些类的某些特定方法的能力。Pointcut接口如下:
public interface Pointcut {
Pointcut TRUE = TruePointcut.INSTANCE;
//切点定位到特定类上
ClassFilter getClassFilter();
//切点定位到特定方法上
MethodMatcher getMethodMatcher();
}
含义:切面由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包括了连接点的定义,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。
2、切点类型
Spring提供了六种类型切点:
静态方法切点:org.springframework.aop.support.StaticMethodMatcherPointcut是静态方法切点的抽象基类,默认情况下它匹配所有的类。 StaticMethodMatcherPointcut包括 两个主要的子类,分别是NameMatchMethodPointcut和AbstractRegexpMethodPointcut,前者提供简单字符串匹配方法签名,而后者使用正则表达式匹配方法签名;
动态方法切点:org.springframework.aop.support.DynamicMethodMatcherPointcut是动态方法切点的抽象基类,默认情况下它匹配所有的类。 DynamicMethodMatcherPointcut类已经过时,可以使用DefaultPointcutAdvisor和DynamicMethodMatcherPointcut动态方法匹配器替代之;
注解切点:org.springframework.aop.support.annotation.AnnotationMatchingPointcut实现类表示注解切点;
表达式切点:org.springframework.aop.support.ExpressionPointcut接口主要是为了支持AspectJ切点表达式语法而定义的接口;
流程切点:org.springframework.aop.support.ControlFlowPointcut实现类表示控制流程切点。ControlFlowPointcut是一种特殊的切点,它根据程序执行堆栈的信息查看目标方法是否由某一个方法直接或间接发起调用,以此判断是否为匹配的连接点;
复合切点:org.springframework.aop.support.ComposablePointcut实现类是为创建多个切点而提供的方便操作类。它所有的方法都返回ComposablePointcut类,这样,我们就可以使用链接表达式对其进行操作,形如:Pointcut pc=new ComposablePointcut().union(classFilter).intersection(methodMatcher).intersection(pointcut)
3、切面类型
切面就是由切点和增强组成。由于增强既包含横切代码,又包含部分的连接点信息(方法前、方法后等的方位信息),所以我们可以仅通过增强类生成一个切面。但切点仅代表目标类连接点的部分信息(类和方法的定位),所以仅有切点,我们无法制作出一个切面,必须结合增强才能制作出切面。
Spring使用org.springframework.aop.Advisor接口表示切面的概念,一个切面同时包含横切代码和连接点信息。
切面可以分为三类:一般切面、切点切面、引介切面,可以通过Spring定义的切面接口清楚的了解切面的分类。类图如下:
Advisor:代表一般切面,它仅包含一个Advice,我们说过,因为Advice包含了横切代码和连接点的信息,所以Advice本身就是一个简单的切面,只不过它代表的横切的连接点是所有目标类的所有方法,因为这个横切面太宽泛,所以一般不会直接使用;
PointcutAdvisor:代表具有切点的切面,它包含Advice和Pointcut两个类,这样我们就可以通过类、方法名以及方法方位等信息灵活地定义切面的连接点,提供更具适用性的切面;
IntroductionAdvisor:代表引介切面,是对应引介增强的特殊切面,它应用于类层面上;
下面我们分析切点切面接口PointcutAdvisor,主要有6个具体的实现类,分别介绍如下:
1、DefaultPointcutAdvisor:最常用的切面类型,它可以通过任意Pointcut和Advice定义一个切面,唯一不支持的是引介的切面类型,一般可以通过扩展该类实现自定义的切面;
2、NameMatchMethodPointcutAdvisor:通过该类可以定义按方法名定义切点的切面;
3、RegexpMethodPointcutAdvisor:对于按正则表达式匹配方法名进行切点定义的切面,该类已经是功能齐备的实现类,一般情况下无须扩展该类,直接配置即可使用;
4、StaticMethodMatcherPointcutAdvisor:静态方法匹配器切点定义的切面,默认情况下,匹配所有的目标类;
5、AspecJExpressionPointcutAdvisor:用于Aspecj切点表达式定义切点的切面;
6、AspecJPointcutAdvisor:用于AspecJ语法定义切点的切面。
下面具体讲解PointcutAdvisor下常用的几个类 。
4、静态普通方法名匹配切面
StaticMethodMatcherPointcutAdvisor代表一个静态方法匹配切面,它通过StaticMethodMatcherPointcut来定义切点,并通过类过滤和方法名来匹配所定义的切点.
业务类Waiter
/**
* 服务员业务类
*/
public class Waiter {
public void greetTo(String name) {
System.out.println("Waiter Greet to " + name);
}
public void serverTo(String name) {
System.out.println("Waiter Server to " + name