BeanFactoryAdvisorRetrievalHelper:從Bean工廠檢索出Advisor們

這個類很重要,是真正去容器中找出全部的Advisor的類緩存

BeanFactoryAdvisorRetrievalHelper是一個Spring AOP內部工具類,該工具類用來從bean容器,也就是BeanFactory中獲取全部Spring的Advisor bean。工具

該工具內部使用了緩存機制,雖然公開的查找方法可能會被調用屢次,但並非每次都會真正查找,而是會利用緩存。this

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;
    }

}
相關文章
相關標籤/搜索