• BeanFactoryAdvisorRetrievalHelper:从Bean工厂检索出Advisor们


    这个类很重要,是真正去容器中找出所有的Advisor的类

    BeanFactoryAdvisorRetrievalHelper是一个Spring AOP内部工具类,该工具类用来从bean容器,也就是BeanFactory中获取所有Spring的Advisor bean。

    该工具内部使用了缓存机制,虽然公开的查找方法可能会被调用多次,但并不是每次都会真正查找,而是会利用缓存。

    public class BeanFactoryAdvisorRetrievalHelper {
        private static final Log logger = LogFactory.getLog(BeanFactoryAdvisorRetrievalHelper.class);
    
        private final ConfigurableListableBeanFactory beanFactory;
        /**
        * 本地会做一个简单的字段缓存
        */
        private volatile String[] cachedAdvisorBeanNames;
    
    
        /**
         * Create a new BeanFactoryAdvisorRetrievalHelper for the given BeanFactory.
         * 对于给定的BeanFactory创建一个BeanFactoryAdvisorRetrievalHelper实例
         */
        public BeanFactoryAdvisorRetrievalHelper(ConfigurableListableBeanFactory beanFactory) {
            Assert.notNull(beanFactory, "ListableBeanFactory must not be null");
            this.beanFactory = beanFactory;
        }
    
    
        /**
         * Find all eligible Advisor beans in the current bean factory,
         * 核心方法,获取所有的Advisors
         */
        public List<Advisor> findAdvisorBeans() {
            // Determine list of advisor bean names, if not cached already.
            String[] advisorNames = this.cachedAdvisorBeanNames;
            if (advisorNames == null) {
                //获取bean容器及其父容器中所有Spring Advisor bean的名称
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Advisor.class, true, false);
                // 将获取到的Advisor bean 的名称记录到 this.cachedAdvisorBeanNames 
                this.cachedAdvisorBeanNames = advisorNames;
            }
            if (advisorNames.length == 0) {
                return new ArrayList<Advisor>();
            }
    
            List<Advisor> advisors = new ArrayList<Advisor>();
            for (String name : advisorNames) {
                 // 针对上面从容器中获取到的所有Advisor bean, 检查它们是否符合条件,
                // 这里检查符合条件的逻辑由谓词isEligibleBean()完成
                // isEligibleBean() 在本类中的缺省实现是:总是返回true,
                // 实际上该类可以被继承,然后重写isEligibleBean()方法实现自己的
                // 符合条件检查逻辑 
                if (isEligibleBean(name)) {
                    // 忽略正在创建中的bean
                    if (this.beanFactory.isCurrentlyInCreation(name)) {
                        if (logger.isDebugEnabled()) {
                            logger.debug("Skipping currently created advisor '" + name + "'");
                        }
                    }
                    else {
                        try {
                            // 遇到了一个真正符合条件的bean,将其实例化,然后放到 advisors 中,
                            // 如果创建过程中遇到异常是因为其依赖bean正在创建中,则先忽略该bean,
                            // 如果是其他异常,抛出异常,中断当前方法
                            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;
        }
    
        /**
         * Determine whether the aspect bean with the given name is eligible.
         * <p>The default implementation always returns {@code true}.
         * @param beanName the name of the aspect bean
         * @return whether the bean is eligible
         */
        protected boolean isEligibleBean(String beanName) {
            return true;
        }
    
    }
  • 相关阅读:
    Debug相关的一些小技巧
    <Information Storage and Management> 读书笔记 之二
    <<Information Storage and Management>>读书笔记 之三
    LINQ to SQL语句(2)之Select/Distinct【转】
    Asp.Net MVC实践 探索UrlRouting并分析UrlHelper (基于ASP.NET MVC Preview 3) 【转】
    MVC学习之分页 【转】
    在 ASP.NET MVC 项目中使用 WebForm 【转】
    Asp.net Mvc Codeplex Preview 5 第三篇 实现Action参数传递繁杂类型 【转】
    jQuery入门[1]-构造函数 【转】
    LINQ to SQL语句(1)之Where【转】
  • 原文地址:https://www.cnblogs.com/mayang2465/p/12141610.html
Copyright © 2020-2023  润新知