spring源码aop解析(一)

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取 2000+ 道 Java 面试题

这里主要看下解析流程笔记,不做详细解析:
xml配置如下

    <aop:config proxy-target-class="true">
         <aop:aspect id="time" ref="timeHandler">
             <aop:pointcut id="addAllMethod" expression="execution(* org.xrq.action.aop.Dao.*(..))" />
             <aop:before method="printTime" pointcut-ref="addAllMethod" />
             <aop:after method="printTime" pointcut-ref="addAllMethod" />
         </aop:aspect>
     </aop:config>

spring.handlers中配置的注册解析器如下:

    public class AopNamespaceHandler extends NamespaceHandlerSupport {
        public void init() {
            //注册<aop:config>解析器
            registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        }
    }

ConfigBeanDefinitionParser 解析文件过程如下:

    class ConfigBeanDefinitionParser implements BeanDefinitionParser {

        public BeanDefinition parse(Element element, ParserContext parserContext) {
            CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
            parserContext.pushContainingComponent(compositeDef);
            //注册一个AbstractAutoProxyCreator对象,为所有对应advisor拦截并生成目标代理对象
            configureAutoProxyCreator(parserContext, element);

            List<Element> childElts = DomUtils.getChildElements(element);
            for (Element elt: childElts) {
                String localName = parserContext.getDelegate().getLocalName(elt);
                if (POINTCUT.equals(localName)) { //解析pointcut节点
                    parsePointcut(elt, parserContext);
                }
                else if (ADVISOR.equals(localName)) { //解析advisor节点
                    parseAdvisor(elt, parserContext);
                }
                else if (ASPECT.equals(localName)) { //解析aspect节点
                    parseAspect(elt, parserContext);
                }
            }

            parserContext.popAndRegisterContainingComponent();
            return null;
        }
        //这里其实就是注册一个beanFacotryProcesser监听每个对象被创建后,扫描所有advisor并判断是否需要生成一个代理对象
        private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
            AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
        }
    }

自动查找advisor列表,注册并拦截生成目标代理对象

    //AOP自动扫描advisor对象,生成代理对象:
    第一种:采用快捷注解
     AopConfigUtils注册自动扫描advisor,拦截并创建代理对象
     InfrastructureAdvisorAutoProxyCreator           
     AspectJAwareAdvisorAutoProxyCreator       //<aop:config> 注册这种
     AnnotationAwareAspectJAutoProxyCreator   //<aop:aspectj-autoproxy> 注册这种
    第二种:  用户自声明
     <!-- 自动代理所有的advisor -->
     <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"> </bean>  
     小记:DefaultAdvisorAutoProxyCreator 自动代理所有的advisor(可指定前缀)

上面几个类都是继承AbstractAdvisorAutoProxyCreator类,下面我们看下具体干了什么?

    //该类主要提供了扫描所有可用的advisor的扫描方法
    public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
        //查找容器中所有的advisor对象
        private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;

        @Override
        public void setBeanFactory(BeanFactory beanFactory) {
            super.setBeanFactory(beanFactory);
            if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
                throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
            }
            initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
        }

        protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            //生成一个扫描Advisor的对象实例
            this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
        }

        @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();
        }

        //查找所有可用的EligibleAdvisors
        protected List<Advisor> findEligibleAdvisors(Class beanClass, String beanName) {
            //容器中所有的Advisors列表
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
            //获取当前类匹配的Advisors列表
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            extendAdvisors(eligibleAdvisors);
            //排序
            if (!eligibleAdvisors.isEmpty()) {
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }

        protected List<Advisor> findCandidateAdvisors() {
            return this.advisorRetrievalHelper.findAdvisorBeans();
        }

        //获取当前类匹配的Advisors列表
        protected List<Advisor> findAdvisorsThatCanApply(
                List<Advisor> candidateAdvisors, Class beanClass, String beanName) {
            //标记
            ProxyCreationContext.setCurrentProxiedBeanName(beanName);
            try {
                //返回所有可用对象
                return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
            }
            finally {
                ProxyCreationContext.setCurrentProxiedBeanName(null);
            }
        }

        //默认返回true,主要由子类负责对现有的Advisors进行刷选,BeanFactoryAdvisorRetrievalHelperAdapter.findAdvisorBeans()会用到
        protected boolean isEligibleAdvisorBean(String beanName) {
            return true;
        }

        private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {

            public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
                super(beanFactory);
            }

        public List<Advisor> findAdvisorBeans() {
            String[] advisorNames = null;
            synchronized (this) { //防止并发
                advisorNames = this.cachedAdvisorBeanNames;
                if (advisorNames == null) {
                    //获取所有Advisor对象名称列表
                    advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
                    this.cachedAdvisorBeanNames = advisorNames;
                }
            }
            //空直接跳过
            if (advisorNames.length == 0) {
                return new LinkedList<Advisor>();
            }
            List<Advisor> advisors = new LinkedList<Advisor>();
            for (String name : advisorNames) { //遍历advisors
                if (isEligibleBean(name)) { //是否满足条件
                    if (this.beanFactory.isCurrentlyInCreation(name)) { //跳过未实例完成的对象
                        if (logger.isDebugEnabled()) {
                            logger.debug("Skipping currently created advisor '" + name + "'");
                        }
                    }
                    else {
                        try {
                            //添加到列表中
                            advisors.add(this.beanFactory.getBean(name, Advisor.class));
                        }
                        catch (BeanCreationException ex) {
                            Throwable rootCause = ex.getMostSpecificCause();
                            if (rootCause instanceof BeanCurrentlyInCreationException) {
                                BeanCreationException bce = (BeanCreationException) rootCause;
                                if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
                                    if (logger.isDebugEnabled()) {
                                        logger.debug("Skipping advisor '" + name +
                                                "' with dependency on currently created bean: " + ex.getMessage());
                                    }
                                    // Ignore: indicates a reference back to the bean we're trying to advise.
                                    // We want to find advisors other than the currently created bean itself.
                                    continue;
                                }
                            }
                            throw ex;
                        }
                    }
                }
            }
            return advisors;
        }

            @Override
            protected boolean isEligibleBean(String beanName) {
                return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
            }
        }

    }

    //对bean进行拦截 并 判断是否需要生成代理对象
    public abstract class AbstractAutoProxyCreator extends ProxyConfig implements SmartInstantiationAwareBeanPostProcessor, BeanClassLoaderAware, BeanFactoryAware, Ordered, AopInfrastructureBean {

        //bean被创建后,执行init方法之前
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            Object cacheKey = getCacheKey(beanClass, beanName);

            if (beanName == null || !this.targetSourcedBeans.containsKey(beanName)) {
                //已经判断过的类型
                if (this.advisedBeans.containsKey(cacheKey)) {
                    return null;
                }
                //需要跳过的类型
                if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                    this.advisedBeans.put(cacheKey, Boolean.FALSE);
                    return null;
                }
            }

            // 如果我们有一个自定义的TargetSource,在这里创建代理。
            //禁止不必要的目标bean的默认实例:TargetSource将以自定义的方式处理目标实例。
            if (beanName != null) {
                TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
                if (targetSource != null) {
                    this.targetSourcedBeans.put(beanName, Boolean.TRUE);
                    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                    Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                    this.proxyTypes.put(cacheKey, proxy.getClass());
                    return proxy;
                }
            }

            return null;
        }

        //判断是否为Advice、Advisor 或 AopInfrastructureBean类型
        protected boolean isInfrastructureClass(Class<?> beanClass) {
            boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                    Advisor.class.isAssignableFrom(beanClass) ||
                    AopInfrastructureBean.class.isAssignableFrom(beanClass);
            if (retVal && logger.isTraceEnabled()) {
                logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
            }
            return retVal;
        }

        //bean被创建后,执行init方法之后
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (!this.earlyProxyReferences.containsKey(cacheKey)) { //实例未初始化完成,跳过
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }

        //获取当前类所有的Advisors对象,并创建一个代理对象
        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            //targetSourcedBeans直接跳过
            if (beanName != null && this.targetSourcedBeans.containsKey(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;
            }

            //判断是否有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;
        }
    }

来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring源码aop解析(一)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏