美文网首页
Spring AOP源码解析(二)

Spring AOP源码解析(二)

作者: anyoptional | 来源:发表于2021-04-21 07:26 被阅读0次

    前言

      上一篇中我们扒拉了一下spring-aop的底裤,详细解读了spring-aop中的各种抽象概念,本篇开始我们一起研究研究spring-aop的织入过程(基于5.2.6.RELEASE)。建议各位同学本地打开一份源码对照食用,效果更佳。

      前方高能!!!本篇重度依赖于上一篇解读的抽象概念,不熟悉的同学请速速撤离,以免误伤。

      正式开始之前,各位同学还请思考一下,在拥有了关于AOP的全局视角之后,如果是你,会怎样有机地结合这些概念来实现织入呢?我听到有同学说利用BeanPostProcessor。嗯,不错,Bean后置处理器给我们提供了这样一个切入点——可以在Bean自动装配完毕、行将可用之前对它进行定制,如果我们在这里返回一个代理对象,那么它就会取代原始对象。具体来说,就是在BeanPostProcessor#postProcessAfterInitialization(...)回调中完成织入并返回新创建的代理对象。那么,真的是这样吗?

    一切从EnableAspectJAutoProxy说起

      EnableAspectJAutoProxy的作用自不必多说,不过我们今天深入一点,探究一下它的源码。这个说白了就是看它通过Import元注解向容器中导入了些什么,我们知道Spring中EnableXXX类型的注解都是代理给Import元注解向容器中导入功能组件的。

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AspectJAutoProxyRegistrar.class})
    public @interface EnableAspectJAutoProxy {
        /**
         * 是基于JDK动态代理还是CGLIB
         */
        boolean proxyTargetClass() default false;
    
        /**
         * 是否需要暴露代理对象到ThreadLocal中
         */
        boolean exposeProxy() default false;
    }
    

    注意到注解中的两个属性也存在于Advised接口,而Advised又保存着AOP配置信息,因此我们可以大胆地猜测这两个属性值最终会同步给Advised

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                          BeanDefinitionRegistry registry) {
            // 向容器中导入一个类型为AnnotationAwareAspectJAutoProxyCreator的Bean
        // 同时设置它的优先级为Ordered.HIGHEST_PRECEDENCE,角色为BeanDefinition.ROLE_INFRASTRUCTURE
            AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
            // 提取EnableAspectJAutoProxy注解的属性
            AnnotationAttributes enableAspectJAutoProxy =
                    AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
            if (enableAspectJAutoProxy != null) {
          // 如果proxyTargetClass=true,同步给AnnotationAwareAspectJAutoProxyCreator
                if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
          // 如果exposeProxy=true,同步给AnnotationAwareAspectJAutoProxyCreator
                if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
                }
            }
        }
    }
    

    AspectJAutoProxyRegistrar做的事情非常简单:

    1. 向容器中导入一个AnnotationAwareAspectJAutoProxyCreator类型的Bean,并设置优先级和角色
    2. 同步EnableAspectJAutoProxy注解的属性值给它

    那么问题来了,这个AnnotationAwareAspectJAutoProxyCreator是个什么鬼呢?看名字的话它是某种自动代理的创建器,那么是不是就是它实现了BeanPostProcessor接口呢?

    Variant AutoProxyCreator

    Hierarchy of AnnotationAwareAspectJAutoProxyCreator
    aj-arch.png

      查看类图,结果确如我们所想,AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,只不过是其父类实现的。好呗,扒就扒到底,AbstractAutoProxyCreator走起。

    What is SmartInstantiationAwareBeanPostProcessor

      题外话,AbstractAutoProxyCreator实现的并不是普通的BeanPostProcessor,而是SmartInstantiationAwareBeanPostProcessor。有些同学可能不太熟悉这个接口,简单说明一下,我们先看它的父接口InstantiationAwareBeanPostProcessor

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
        /**
         * 在Bean创建之前调用,如果返回一个非空对象,就会跳过标准的Spring Bean创建流程而直接来到
         * postProcessAfterInitialization(...),具体逻辑可查看AbstractAutowireCapableBeanFactory#createBean(...)
         * 也就是说,如果我们想自己全盘接管Bean的生命周期,就可以使用这个回调
         */
        @Nullable
        default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }
    
        /**
         * 是否需要为刚创建好的Bean执行自动注入等标准流程,true表示执行标准的Spring Bean初始化流程,
         * false表示由用户自己控制初始化流程,具体逻辑可查看AbstractAutowireCapableBeanFactory#populateBean(...)
         */
        default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            return true;
        }
    
        /**
         * 在PropertyValues应用到目标Bean上之前,给用户一个机会去修改PropertyValues,这一步其实在
         * BeanFactoryPostProcessor#postProcessBeanFactory(...)中也能实现,只是没有这里来得方便
         */
        @Nullable
        default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, 
                                                   String beanName) throws BeansException {
            return null;
        }
    
        /**
         * 已由#postProcessProperties(...)代替
         */
        @Deprecated
        @Nullable
        default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, 
                                                       Object bean, String beanName) throws BeansException {
            return pvs;
        }
    }
    

    spring-context中,CommonAnnotationBeanPostProcessor就实现了InstantiationAwareBeanPostProcessor接口用以支持javax.annotation.Resource注解。接下来是SmartInstantiationAwareBeanPostProcessor

    public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
        /**
         * 预测#postProcessBeforeInstantiation(...)的回调参数beanClass,主要还是用来做type match
         */
        @Nullable
        default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }
    
        /**
       * 返回候选的构造函数,用来决定是否采用autowire by constructor这种装配策略,
       * 具体逻辑可查看AbstractAutowireCapableBeanFactory#createBeanInstance(...)
         */
        @Nullable
        default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, 
                                                              String beanName) throws BeansException {
            return null;
        }
    
        /**
         * Spring解决循环依赖的思路是提前创建 + 缓存,#getEarlyBeanReference(...)给了我们一个机
         * 会去访问这个被提前创建的Bean,因此我们可以在这里提前创建代理对象被返回,具体逻辑可查看
         * AbstractAutowireCapableBeanFactory#getEarlyBeanReference(...)
         * NOTE: 因为循环依赖的关系,这里传递进来的Bean是没有完全初始化好的,换句话说客户端是不能直接使用的
         */
        default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    

    AbstractAutoProxyCreator是如何执行织入的

    Implementing SmartInstantiationAwareBeanPostProcessor

      好了,言归正题,回到AbstractAutoProxyCreator,挑出它对SmartInstantiationAwareBeanPostProcessor的实现部分。

        /**
       * 换个角度理解,如果目标对象已经被包装过,那么它的类型肯定
       * 会发生改变,因此也就需要一种机制来告诉容器包装后类型,否则
       * 后续类型匹配就会出错,这个机制就是#predictBeanType(...)
       */
        @Override
        @Nullable
        public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
            if (this.proxyTypes.isEmpty()) {
                return null;
            }
        // 获取缓存key
            Object cacheKey = getCacheKey(beanClass, beanName);
        // proxyTypes的类型是Map<Object, Class<?>>
        // 不管是JDK动态代理,还是CGLIB动态生成子类,最终都会改变
        // 目标对象在容器中的类型,proxyTypes中保存着包装后的类型
            return this.proxyTypes.get(cacheKey);
        }
    
        @Override
        public Object getEarlyBeanReference(Object bean, String beanName) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // earlyProxyReferences的类型是Map<Object, Object>
        // getEarlyBeanReference(...)是最早能够访问到目标对象的地方
        // 然而,目标对象可能会在后续的后处理中被改变,比如被其它的处理器修改。
        // 但是只要在earlyProxyReferences中保存着原始目标对象,后续就可以
        // 检测目标对象是否真的被改变了
            this.earlyProxyReferences.put(cacheKey, bean);
        // 尝试包装目标对象,画重点,织入的核心逻辑
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
            Object cacheKey = getCacheKey(beanClass, beanName);
            // targetSourcedBeans中保存着通过自定义TargetSourceCreator创建的目标对象
        // 前面说过,#postProcessBeforeInstantiation(...)这个回调给了客户端全盘
        // 接管Bean生命周期的机会,TargetSourceCreator这个工厂接口就是设计来让客户
        // 端自行处理Bean的创建和属性注入等逻辑的。换言之,通过自定义TargetSourceCreator
        // 返回的目标对象被认为是完全初始化了的,并且会跳过标准的Spring Bean生命周期管理,那么
        // 这里就是最后的机会来完成织入并返回代理对象了
            if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
          // advisedBeans的类型是Map<Object, Boolean>
          // 如果值为false,表示当前这个Bean不需要被代理
          // 值为true,表示已经被代理过了
          // 那么如果不需要代理,肯定就直接返回了
          // 如果已经代理过了,自然也不需要二次代理
          // 所以这里才用containsKey(...)判断一下
                if (this.advisedBeans.containsKey(cacheKey)) {
                    return null;
                }
          // 1、isInfrastructureClass()检测Bean所属的类是不是Spring AOP的支撑类
          // 比如Advisor、Pointcut等等,这些类型是不需要被代理的
          // 2、shouldSkip(...)给了子类一个机会来决定 beanClass + beanName 二元组
          // 对应的Bean是不是不用进行代理
                if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                    this.advisedBeans.put(cacheKey, Boolean.FALSE);
                    return null;
                }
            }
    
        // 如果用户确实需要全盘接管目标对象的生命周期
        // 那么这里是最后一个机会来完成织入并返回代理对象了
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
                if (StringUtils.hasLength(beanName)) {
            // 记录下来
                    this.targetSourcedBeans.add(beanName);
                }
          // 现在,目标对象已经到位 --> 从TargetSource中获取
          // 接下来只要知道可以作用在目标对象上的Advisor都有
          // 哪些就可以着手创建代理了
          
          // step 1: 模板方法,由子类实现,返回所有可能的Advisor
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
          // step 2: 根据已经掌握的信息 targetSouce + Advisors 来创建代理
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
          // 代理创建完成以后,把它的类型记下来
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        
            return null;
        }
    
        @Override
        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
            if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
          // 前面说过,earlyProxyReferences中保存着bean的原始引用
          // 现在只需要简单判断一下就知道它有没有在其它地方被修改
          // 如果是,那就不得不重新尝试一下对它进行代理了
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }
    

    如果不考虑自定义TargetSourceCreator这种非常规流程,AbstractAutoProxyCreator一共有两个机会来完成织入,一处在getEarlyBeanReference(...),另一处在postProcessAfterInitialization(...)。这两处都调用了wrapIfNecessary(...)来完成最后的织入,继续往下看。

    wrapIfNecessary
        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            // 如果用户自行控制生命周期,就什么都不做
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
        // 对不需要被代理的类型,也什么都不做
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
        // 对可能需要被代理类型,进一步检查它是否真的需要被代理
        // 这一步的检测逻辑同 #postProcessBeforeInstantiation(...)
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
        // step 1: 通过模板方法获取所有Advisor
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        // 如果不为空,也就是配置了Advice,当然就需要被代理了
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
          // strp 2: 根据 目标对象 + Advisors 这两份信息来创建代理
          // createProxy(...)会根据配置信息来创建代理(jdk dynamic proxy/cglib subclassing)
          // 并且,Advisors经过处理后会组成一个拦截器链,这一部分的内容比较复杂,我们下篇再说
                Object proxy = createProxy(
                        bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
          // 记录下代理对象的类型
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
            // 没有找到任何Advisor,也就是说没有配置任何Advice
        // 那还代理给毛,自然就是false了
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    

    wrapIfNecessary(...)postProcessBeforeInstantiation(...)做的事情差不多,核心逻辑其实只有两步:

    1. 获取可以作用在目标对象上的Advisor集合
    2. 将第1步获取到的Advisor list转换成Interceptor list并安装到Join point上,说人话就是创建代理对象

    createProxy(...)整个流程比较复杂,涉及到Advice的适配和扩展、拦截器链的初始化和安装、代理的创建等等,我们下篇再说。getAdvicesAndAdvisorsForBean(...)是一个模板方法,实现它的是AbstractAutoProxyCreator的子类AbstractAdvisorAutoProxyCreator,接下来我们分析一下getAdvicesAndAdvisorsForBean(...)

    AbstractAdvisorAutoProxyCreator是如何筛选Advisor的

    getAdvicesAndAdvisorsForBean
        @Override
        @Nullable
        protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
                                                      @Nullable TargetSource targetSource) {
            List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
            if (advisors.isEmpty()) {
                return DO_NOT_PROXY;
            }
            return advisors.toArray();
        }
    

    可以看到,它代理给了findEligibleAdvisors(...),继续跟踪。

        protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 获取BeanFactory中所有的Advisor
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // Sping AOP中Advisor的类型主要是PointcutAdvisor
        // 这一步核心逻辑就是用Pointcut来对Advisor进行筛选
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        // 扩展方法,给子类一个增删改Advisor的机会
            extendAdvisors(eligibleAdvisors);
            if (!eligibleAdvisors.isEmpty()) {
          // 对Advisor进行排序,默认通过Spring标准的Ordered接口和@Order注解指定优先级
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }
    

    findEligibleAdvisors(...)的流程还是比较清晰的:

    1. 找出容器中所有的Advisor
    2. 通过Pointcut进行筛选
    3. 对剩下的Advisor进行排序
    findCandidateAdvisors
        protected List<Advisor> findCandidateAdvisors() {
            Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
            return this.advisorRetrievalHelper.findAdvisorBeans();
        }
    

    发现它又代理给了advisorRetrievalHelper#findAdvisorBeans()

        public List<Advisor> findAdvisorBeans() {
            // 先读缓存
        String[] advisorNames = this.cachedAdvisorBeanNames;
            if (advisorNames == null) {
          // 缓存没有的话,从BeanFactory中一次性把所有的Advisor Bean的名称获取出来
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Advisor.class, true, false);
                this.cachedAdvisorBeanNames = advisorNames;
            }
        // BeanFactory中也没有,那就真的没有了
            if (advisorNames.length == 0) {
                return new ArrayList<>();
            }
    
        // 否则的话,根据beanName挨个调用getBean(...)
            List<Advisor> advisors = new ArrayList<>();
            for (String name : advisorNames) {
          // 首先判断一下这个name所代表的Advisor是否符合条件,默认返回true
          // 可由AbstractAdvisorAutoProxyCreator及其子类进行改写,比如
          // InfrastructureAdvisorAutoProxyCreator就要求Advisor的角色
          // 必须是ROLE_INFRASTRUCTURE,所以@EnableCaching/@EnableTransactionManagement
          // 导入的一票Advisor的role都是ROLE_INFRASTRUCTURE
                if (isEligibleBean(name)) {
            // 跳过正在初始化的Advisor,毕竟这种的拿了也没用
                    if (this.beanFactory.isCurrentlyInCreation(name)) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Skipping currently created advisor '" + name + "'");
                        }
                    }
                    else {
                        try {
                // 逐个获取
                            advisors.add(this.beanFactory.getBean(name, Advisor.class));
                        }
                        catch (BeanCreationException ex) {
                // 如果目标对象和附加在它之上的Advisor间存在循环依赖
                // 这也是抛出BeanCurrentlyInCreationException异常的原因
                // 对这种情况,忽略这个Advisor
                // 个人感觉这种情况是否还是抛出异常比较好?
                            Throwable rootCause = ex.getMostSpecificCause();
                            if (rootCause instanceof BeanCurrentlyInCreationException) {
                                BeanCreationException bce = (BeanCreationException) rootCause;
                                String bceBeanName = bce.getBeanName();
                                if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                                    if (logger.isTraceEnabled()) {
                                        logger.trace("Skipping advisor '" + name +
                                                "' with dependency on currently created bean: " + ex.getMessage());
                                    }
                                    continue;
                                }
                            }
                            throw ex;
                        }
                    }
                }
            }
            return advisors;
        }
    
    findAdvisorsThatCanApply
        protected List<Advisor> findAdvisorsThatCanApply(
                List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
            // 在ThreadLocal中记录一下beanName
        // 用在spring自定义的 bean() AspectJ表达式中,不是很常用
            ProxyCreationContext.setCurrentProxiedBeanName(beanName);
            try {
                return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
            }
            finally {
                ProxyCreationContext.setCurrentProxiedBeanName(null);
            }
        }
    

    核心逻辑都在AopUtils中了。

        public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
            if (candidateAdvisors.isEmpty()) {
                return candidateAdvisors;
            }
            List<Advisor> eligibleAdvisors = new ArrayList<>();
        // IntroductionAdvisor我们就不说了,用得比较少
            for (Advisor candidate : candidateAdvisors) {
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }
            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            for (Advisor candidate : candidateAdvisors) {
                if (candidate instanceof IntroductionAdvisor) {
                    // already processed
                    continue;
                }
          // 判断Advisor能否适用于此beanClass
                if (canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }
            return eligibleAdvisors;
        }
    
        public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        // 忽略IntroductionAdvisor吧,我们不讲它
        // 毕竟PointcutAdvisor几乎就能代表spring中的Advisor了
            if (advisor instanceof IntroductionAdvisor) {
                return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
            }
        // 如果是PointcutAdvisor
            else if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pca = (PointcutAdvisor) advisor;
          // 使用Pointcut进行筛选
                return canApply(pca.getPointcut(), targetClass, hasIntroductions);
            }
            else {
          // Pointcut都没有的话默认它可以
          // 简单理解,这是一种generic advisor
                return true;
            }
        }
    
      public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        // 首先看看类型是否匹配
        if (!pc.getClassFilter().matches(targetClass)) {
          return false;
        }
        
            // Special case: MethodMatcher.TRUE 对任何方法都返回match
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        if (methodMatcher == MethodMatcher.TRUE) {
                // 自然没有判断的必要
          return true;
        }
    
        // 忽略Introduction吧
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
          introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }
    
        Set<Class<?>> classes = new LinkedHashSet<>();
        // 获取targetClass的原始类型,只有原始类型上才可能存在用户定义的方法
        // 也只有这些方法才有必要判断它是否匹配
        // 1. 不能是jdk dymamic proxy,jdk dynamic proxy上就不可能有
        if (!Proxy.isProxyClass(targetClass)) {
          // 2. 虽然不是jdk dynamic proxy,但有可能是cglib动态生成的子类啊,
          // cglib动态生成的子类也不可能有,所以需要获取一下user class
          classes.add(ClassUtils.getUserClass(targetClass));
        }
        
        // targetClass所实现接口也获取一下,接口中会定义方法,
        // 方法上可能有注解,而这些注解,有可能就是判断条件,比如说
        // spring-tx的@Transactional是可以标注在接口上的
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    
        for (Class<?> clazz : classes) {
          // 这没啥说的了,所有方法拿出来,逐个使用MethodMatcher判断一下
          // 这里不涉及isRuntime()的情况,那种情况需要方法被实际调用了才能判断
          // 对jdk dynamic proxy来说就是InvocationHandler#invoke(...)被调用的时候
          Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
          for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ?
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                methodMatcher.matches(method, targetClass)) {
              return true;
            }
          }
        }
    
        return false;
      }
    
    sortAdvisors
        protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
            AnnotationAwareOrderComparator.sort(advisors);
            return advisors;
        }
    

    默认的排序策略是很简单的,根据Advisor实现的Ordered接口或标注的Order注解提供的优先级进行排序。

    结语

      本篇我们从EnableAspectJAutoProxy注解着手,一步一步分析了spring-aop是如何通过BeanPostProcessor来执行织入的,下一篇我们一起看看创建动态代理的全流程吧~~

    相关文章

      网友评论

          本文标题:Spring AOP源码解析(二)

          本文链接:https://www.haomeiwen.com/subject/phrmlltx.html