1.增强与切点
在介绍增强时,我们注意到一个问题:增强被织入到目标类的所有方法中。
假设我们希望有选择地织入到目标类某些特定的方法中,就需要使用切点进行目标连接点的定位了。描述连接点是进行AOP编程最主要的一项工作。
Spring通过org.springframework.aop.Pointcut接口描述切点,Pointcut有两个方法:getClassFilter() 以及 getMethodMatcher()
使用这个方法可以返回一个ClassFilter,通过ClassFilter(将增强)定位到某些特定的类上。
public ClassFilter getClassFilter(){
//切点类匹配规则:为Waiter的类或子类
return new ClassFilter(){
public boolean matches(Class clazz){
return Waiter.class.isAssignableFrom(clazz);
}
};
}//PS:这里不是切点的代码而是在切面中关于切点描述的代码,放上来只是为了增加理解
PS:这里不是切点的代码而是在切面中关于切点描述的代码,放上来只是为了增加理解。
通过matches起到一个MethodMatcher定位到某些特定的方法上,这样Pointcut就拥有了描述某些类的某些特定方法的能力。
public boolean matches(Method method, Class<?> arg1){
//切点方法匹配名称原则,增强到greetTo方法上
return "greetTo".equals(method.getName());
}//PS:这里不是切点的代码而是在切面中关于切点描述的代码,放上来只是为了增加理解
Spring支持两种方法匹配器:静态方法匹配器和动态方法匹配器。所谓静态方法匹配器,它仅对方法名签名(包括方法名和入参类型及顺序)进行匹配:而动态方法匹配器,**会在运行期间检查方法的入参的值。**静态匹配仅会判别一次,而动态匹配因为每次调用方法的入参都可能不一样,所以每次调用方法都必须判断,因此,动态匹配对性能的影响很大。一般情况下,动态匹配不常使用。
2.切面类型
Spring使用org.springframework.aop.Advisor接口表示切点的概念,一个切面同时包含横切代码和连接点的信息。
我们一般接触的切面为PointcutAdvisor(即具有切点的切面), 它包含Advice和Pointcut两个类,这样我们就可以通过类、方法名以及方法方位等信息灵活地定义切面的连接点,提供更具适应性的切面。
2.1 静态普通方法名匹配切面
StaticMethodMatcherPointcutAdvisor代表一个静态方法匹配切面
public class Waiter {
public void greetTo(String name){
System.out.println("waiter greet to"+name+"...");
}
public void serveTo(String name){
System.out.println("Waiter serve to"+name+"...");
}
}
Waiter有两个方法,分别是greetTo()以及serveTo()。
public class Seller {
public void greetTo(String name){
System.out.println("seller greet to"+name+"...");
}
}
Seller拥有一个和Waiter相同名称的方法greetTo()。现在,我们希望通过StaticMethodMatcherPointcutAdvisor定义一个切面,在Waiter#greetTo()方法调用前织入一个增强,即连接点为Waiter#greetTo()方法调用前的位置。
import java.lang.reflect.Method;
import org.springframework