Spring基于注解形式的 AOP的原理流程及源码解析(四)

我们接着上篇博客继续讲。在上篇博客中,讲述的是正在实例化的Bean的beanClass和Spring容器内所有的切面Advisor进行匹配的过程。这个过程如果返回了匹配上的Advisor(一个或多个),则表明这个Bean应该被代理;如果返回的结果为空,则这个Bean不会被代理。
代码块1

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //如果这一步返回的结果不是空集合,则表明有匹配上的切面Advisor
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //对返回的切面集合做拓展
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            //对切面集合做排序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

    protected void extendAdvisors(List<Advisor> candidateAdvisors) {
        //将ExposeInvocationInterceptor.ADVISOR实例加入到切面集合的首位元素,这个元素在生成AOP对象是要用到
        AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
    }

}

AbstractAdvisorAutoProxyCreator有对切面排序的方法,不过其子类AspectJAwareAdvisorAutoProxyCreator重写了排序方法,正常应该调用其子类的方法
代码块2

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {  
    //按Ordered接口及@Order的序号值来作为排序的准则
    protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
        AnnotationAwareOrderComparator.sort(advisors);
        return advisors;
    }
}

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

    private static final Comparator<Advisor> DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();

    protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
        List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
                new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());
        for (Advisor element : advisors) {
            partiallyComparableAdvisors.add(
                    //主要看DEFAULT_PRECEDENCE_COMPARATOR它的排序规则
                    new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
        }
        List<PartiallyComparableAdvisorHolder> sorted =
                PartialOrder.sort(partiallyComparableAdvisors);
        if (sorted != null) {
            List<Advisor> result = new ArrayList<Advisor>(advisors.size());
            for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
                result.add(pcAdvisor.getAdvisor());
            }
            return result;
        }
        else {
            return super.sortAdvisors(advisors);
        }
    }
}

常量DEFAULT_PRECEDENCE_COMPARATOR是一个AspectJPrecedenceComparator对象,查看其排序的规则:
代码块3

class AspectJPrecedenceComparator implements Comparator<Advisor> {

    private static final int HIGHER_PRECEDENCE = -1;
    private static final int SAME_PRECEDENCE = 0;
    private static final int LOWER_PRECEDENCE = 1;
    public AspectJPrecedenceComparator() {
        this.advisorComparator = AnnotationAwareOrderComparator.INSTANCE;
    }

    public int compare(Advisor o1, Advisor o2) {
        //先根据@Order及Ordered的序号比较
        int advisorPrecedence = this.advisorComparator.compare(o1, o2);
        //如果没有这两个条件,返回的优先级相同,则按另一种规则比较
        //Advisor实例是InstantiationModelAwarePointcutAdvisorImpl类型,所以declaredInSameAspect符合条件
        if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) {
            advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);
        }
        return advisorPrecedence;
    }

    private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) {
        //看InstantiationModelAwarePointcutAdvisorImpl的determineAdviceType()方法
        //@After,@AfterReturning,@AfterThrowing这三个注解是afterAdvice
        boolean oneOrOtherIsAfterAdvice =
                (AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
        //Order按@Around, @Before, @After, @AfterReturning, @AfterThrowing的顺序
        int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);

        if (oneOrOtherIsAfterAdvice) {
            // the advice declared last has higher precedence
            //排序是对待织入一个Bean的多个切面进行排序,这些切面可能分布在不同的切面定义类里,也可能有多个切面定义在同一个类里
            //afterAdvice有着比其他的advice更高的优先级,@After, @AfterReturning, @AfterThrowing这三个按倒序排列
            //@Around, @Before这两个注解顺序排序,afterAdvice排在正常的advice前面
            //排序后的顺序应该是:@AfterThrowing,@AfterReturning,@After,@Around,@Before
            //顺序可能不正确,大家可以自己测试下,从代码上看是如此的
            if (adviceDeclarationOrderDelta < 0) {
                // advice1 was declared before advice2
                // so advice1 has lower precedence
                return LOWER_PRECEDENCE;
            }
            else if (adviceDeclarationOrderDelta == 0) {
                return SAME_PRECEDENCE;
            }
            else {
                return HIGHER_PRECEDENCE;
            }
        }
        else {
            // the advice declared first has higher precedence
            if (adviceDeclarationOrderDelta < 0) {
                // advice1 was declared before advice2
                // so advice1 has higher precedence
                return HIGHER_PRECEDENCE;
            }
            else if (adviceDeclarationOrderDelta == 0) {
                return SAME_PRECEDENCE;
            }
            else {
                return LOWER_PRECEDENCE;
            }
        }
    }
}

接着上文将,合适的切面已经找到了,而且添加了一个头节点,对切面进行了排序,接下里就需要使用切面和Bean对象动态生成代理对象了:
代码块4

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        //找到了合适的切面数组
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //开始创建代理对象
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        //拷贝AOP配置,@EnableAspectJAutoProxy的proxyTargetClass值等
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        //如果有Advisor等类型的Bean,则实例化,加入Advisor数组,排在有注解生成的Advisor的前端
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);
        }

        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(getProxyClassLoader());
    }
}

通过代理工厂ProxyFactory生成代理实例:
代码块5

public class ProxyFactory extends ProxyCreatorSupport {

    public Object getProxy(ClassLoader classLoader) {
        //createAopProxy()一般生成ObjenesisCglibAopProxy实例
        return createAopProxy().getProxy(classLoader);
    }

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            //如果被代理的Class是一个接口,或者被代理类是一个Proxy代理生成的类,则生成JdkDynamicAopProxy(一般不会)
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }
}

接下去的就是通过Bean和Advisors生成代理对象了,很多都是CGLIB的代码,很晦涩麻烦,就不讲了。
接下来将一些通过CGLIB实现AOP的其他的知识点。

  1. 通过CGLIB生成的代理对象,持有原始Bean对象,同时继承自原始BeanClass
  2. 动态生成的对象的类名上含有 $$ 符号,所以判断一个对象是不是CGLIB生成的代理对象就看其类名上是否含有$$,详情看ClassUtils.isCglibProxy(Object)方法
  3. 当通过Advisors和Bean生成代理对象时,每一个Advisor会以MethodInterceptor的形式保存在代理对象中,每调用一个原始Bean的方法,均会触发所有的Advisor方法,而不仅仅是匹配注解表达式的方法,比如toString()
  4. JDK Proxy生成的动态代理对象类名以Proxy$+数字组成,代理对象继承自Proxy对象,实现了被代理对象的接口。数字代表着是jdk动态代理生成的第几个代理对象。
    原文作者:AOP
    原文地址: https://blog.csdn.net/qq_27529917/article/details/78454875
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞