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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/elim168/article/details/78445908

编程式的自定义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日)

展开阅读全文

没有更多推荐了,返回首页