Spring Aop(十六)——编程式的自定义Advisor

来源:互联网 发布:c语言课程设计题目汇总 编辑:程序博客网 时间:2024/05/17 22:45

编程式的自定义Advisor

概述

大多数情况下,我们的Aop应用都可以通过Spring的Aop配置来进行(不管是基于注解的,还是基于XML配置的)。Spring Aop的核心就是AdvisorAdvisor接口中暂时有用的就是getAdvice()方法,而isPerInstance()方法官方说暂时还没有应用到,生成的Advisor是单例还是多例不由isPerInstance()的返回结果决定,而由自己在定义bean的时候控制。

public interface Advisor {    Advice getAdvice();    boolean isPerInstance();}

我们在使用Advisor时不会直接实现Advisor的接口,而是实现Advisor接口的子接口,PointcutAdvisorIntroductionAdvisorIntroductionAdvisor个人感觉用处不大,我们之前介绍的@DeclareParents<aop:declare-parents/>就属于IntroductionAdvisor使用,它们对应的是DeclareParentsAdvisor。剩下的大部分应用的都是PointcutAdvisorPointcutAdvisor接口的定义如下。

public interface PointcutAdvisor extends Advisor {    Pointcut getPointcut();}

我们可以看到它在Advisor接口的基础上新增了一个getPointcut()方法,用以指定我们的Advisor需要应用到哪些Pointcut,即哪些方法调用。编程式的Pointcut定义之前已经介绍过了,它不属于本文介绍的范畴,这里就不再赘述了,对这块不是很了解的读者建议从头看起,笔者的博文是系列博文,当然了也可以暂时先略过,直接看笔者下文的示例。

实现自定义的Advisor

以下是笔者实现的一个自定义的Advisor,是实现的PointcutAdvisor接口。应用的AdviceMethodBeforeAdvice的实现;应用的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)来应用我们自定义的AdvisorAdvisedSupport的子类中有ProxyCreatorSupport
- 如果我们的项目中已经应用了<aop:aspectj-autoproxy/><aop:config>,那么我们定义在bean容器中的Advisor bean会自动应用到匹配的bean上。这个在《Spring Aop原理之自动创建代理对象》一文中有详细介绍。
- 如果项目中没有应用<aop:aspectj-autoproxy/><aop:config>,我们就需要自己定义BeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreatorAbstractAdvisorAutoProxyCreator类型的bean了。或者是定义AnnotationAwareAspectjAutoProxyCreatorAspectJAwareAdvisorAutoProxyCreator类型的bean,其实<aop:aspectj-autoproxy/>就是自动定义了AnnotationAwareAspectjAutoProxyCreator类型的bean,<aop:config>就是自动定义了AspectJAwareAdvisorAutoProxyCreator类型的bean。这样在创建bean后都会寻找匹配的Advisor建立对应的代理对象。这些都在《Spring Aop原理之自动创建代理对象》一文中有详细介绍,细节这里就不再赘述。

(注:本文是基于Spring4.1.0所写,写于2017年5月16日)

原创粉丝点击