美文网首页
6.3Spring的AOP的解析——使用实例化bean后的处理的

6.3Spring的AOP的解析——使用实例化bean后的处理的

作者: szhlcy | 来源:发表于2019-02-12 11:20 被阅读0次

    上面将来完成AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这个类怎么完成AOP的操作的呢。先看看这个类的层次结构。

    image
      在类的层级中,我们看到AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessorAfterInitalization方法,而我们对于AOP逻辑的分析就由此开始。
    在父类AbstractAutoProxyCreator的postProcessAfterInitialization中代码如下:
        //如果bean被标识为子类代理的bean,则使用配置的拦截器创建代理
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean != null) {
            //根据给定的bean的class和那么构建出key,格式:beanClassName_beanName
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                //判断是否这个bean已经被代理过
                if (!this.earlyProxyReferences.containsKey(cacheKey)) {
                //如果它适合被代理,则需要封装制定的bean
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }
        
        protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) {
        //beanName是否存在
            if (StringUtils.hasLength(beanName)) {
            //如果beanName存在,并且class是FactoryBean类型的,则在beanName前面加上FactoryBean的前缀,否则就用beanName
                return (FactoryBean.class.isAssignableFrom(beanClass) ?
                        BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
            }
            else {
                return beanClass;
            }
        }
    
        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            //如果已经处理过,直接返回bean
            if (beanName != null && this.targetSourcedBeans.containsKey(beanName)) {
                return bean;
            }
            //如果无需增强也直接返回(需要和不需要增强的bean都会记录下来,根据value来判断是不是需要代理)
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            //给定的bean类是否代表一个基础类(默认实现将Advices,Advisors和AopInfrastructureBeans视为基础结构类),基础设施类不应代理
            //或者配置了指定bean不需要自动代理(初始化现有bean实例时“原始实例”约定的后缀.ORIGINAL,例如com.mypackage.MyClass.ORIGINAL)
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                //如果是不需要代理的需要记录下来
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            //如果该bean中存在需要被增强的方法则创建代理
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            //如果获取到了增强则需要针对增强创建代理
            if (specificInterceptors != DO_NOT_PROXY) {
                //保存需要增强的bean
                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;
        }
    
    

     函数中已经看到了代理创建的雏形。在真正开始之前还需要经过一些判断,比如是否已经处理过或者是否需要跳过的bean,真正创建代理的代码是从getAdviceAndAdvisorsForBean开始的。
     创建代理主要包含两个步骤

    1. 获取增强方法获取增强器
    2. 根据获取的增强进行代理

    首先看获取增强并实现增强方法的实现在;

     
    
        protected static final Object[] DO_NOT_PROXY = null;
        
        @Override
        protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) {
        //查找符合条条件的代理
            List advisors = findEligibleAdvisors(beanClass, beanName);
            if (advisors.isEmpty()) {
                return DO_NOT_PROXY;
            }
            return advisors.toArray();
        }
        
        protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
            //找到要在自动代理中使用的所有候选代理对象(所有Advisor接口的实现类)
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
            //从候选的代理对象中搜索,找到可以应用于指定bean的所有代理,根据切点表达式来判断
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            //如果代理类集合不为空的时候,检查所有代理类中是不是包含AspectJ(AspectJ表达式)代理,如果包含则需要把ExposeInvocationInterceptor类作为连接器链的第一个
            extendAdvisors(eligibleAdvisors);
            if (!eligibleAdvisors.isEmpty()) {
                //按照先后顺序进行排序
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }   
    

      对于指定bean的增强方法的获取一定包含两个步骤,获取所有的增强以及寻找所有增强中适用于bean的增强并应用。如果无法找到对应的增强其就会返回DO_NOT_PROXY,其中DO_NOT_PROXY=null;
     对于增强的选择也是比较复杂的候选代理的获取

    相关文章

      网友评论

          本文标题:6.3Spring的AOP的解析——使用实例化bean后的处理的

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