编程式的自定义Advisor
概述
大多数情况下,我们的Aop应用都可以通过Spring的Aop配置来进行(不管是基于注解的,还是基于XML配置的)。Spring Aop的核心就是Advisor
,Advisor
接口中暂时有用的就是getAdvice()
方法,而isPerInstance()
方法官方说暂时还没有应用到,生成的Advisor
是单例还是多例不由isPerInstance()
的返回结果决定,而由自己在定义bean的时候控制。
public interface Advisor {
Advice getAdvice();
boolean isPerInstance();
}
我们在使用Advisor
时不会直接实现Advisor
的接口,而是实现Advisor
接口的子接口,PointcutAdvisor
或IntroductionAdvisor
。IntroductionAdvisor
个人感觉用处不大,我们之前介绍的@DeclareParents
和<aop:declare-parents/>
就属于IntroductionAdvisor
使用,它们对应的是DeclareParentsAdvisor
。剩下的大部分应用的都是PointcutAdvisor
。PointcutAdvisor
接口的定义如下。
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
我们可以看到它在Advisor接口
的基础上新增了一个getPointcut()
方法,用以指定我们的Advisor需要应用到哪些Pointcut
,即哪些方法调用。编程式的Pointcut
定义之前已经介绍过了,它不属于本文介绍的范畴,这里就不再赘述了,对这块不是很了解的读者建议从头看起,笔者的博文是系列博文,当然了也可以暂时先略过,直接看笔者下文的示例。
实现自定义的Advisor
以下是笔者实现的一个自定义的Advisor
,是实现的PointcutAdvisor
接口。应用的Advice
是MethodBeforeAdvice
的实现;应用的Pointcut
简单匹配所有类的方法名为find
的方法调用。
public class MyAdvisor implements PointcutAdvisor {
@Override
public Advice getAdvice() {
return new MethodBeforeAdvice() {
@Override
public void before(Method method,
Object[] args, Object target) throws Throwable {
System.out.println("BeforeAdvice实现,在目标方法被调用前调用,目标方法是:"
+ method.getDeclaringClass().getName() + "."
+ method.getName());
}
};
}
@Override
public boolean isPerInstance() {
return true;
}
@Override
public Pointcut getPointcut() {
/**
* 简单的Pointcut定义,匹配所有类的find方法调用。
*/
return new Pointcut() {
@Override
public ClassFilter getClassFilter() {
return ClassFilter.TRUE;
}
@Override
public MethodMatcher getMethodMatcher() {
return new MethodMatcher() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
String methodName = method.getName();
if ("find".equals(methodName)) {
return true;
}
return false;
}
@Override
public boolean isRuntime() {
return false;
}
@Override
public boolean matches(Method method, Class<?> targetClass,
Object[] args) {
return false;
}
};
}
};
}
}
配置使用自定义的Advisor
有了自定义的Advisor
后我们应该如何来应用它呢?这又区分好几种情况。
- 如果是自己通过编程应用
ProxyFactory
,或者说是应用ProxyCreatorSupport
来创建代理对象,那么我们通过AdvisedSupport.addAdvisor(Advisor advisor)
来应用我们自定义的Advisor
。AdvisedSupport
的子类中有ProxyCreatorSupport
。 - 如果我们的项目中已经应用了
<aop:aspectj-autoproxy/>
或<aop:config>
,那么我们定义在bean容器中的Advisor
bean会自动应用到匹配的bean上。这个在《Spring Aop原理之自动创建代理对象》
一文中有详细介绍。 - 如果项目中没有应用
<aop:aspectj-autoproxy/>
或<aop:config>
,我们就需要自己定义BeanNameAutoProxyCreator
、DefaultAdvisorAutoProxyCreator
等AbstractAdvisorAutoProxyCreator
类型的bean了。或者是定义AnnotationAwareAspectjAutoProxyCreator
或AspectJAwareAdvisorAutoProxyCreator
类型的bean,其实<aop:aspectj-autoproxy/>
就是自动定义了AnnotationAwareAspectjAutoProxyCreator
类型的bean,<aop:config>
就是自动定义了AspectJAwareAdvisorAutoProxyCreator
类型的bean。这样在创建bean后都会寻找匹配的Advisor
建立对应的代理对象。这些都在《Spring Aop原理之自动创建代理对象》
一文中有详细介绍,细节这里就不再赘述。
(注:本文是基于Spring4.1.0所写,写于2017年5月16日)