這個類很重要,是真正去容器中找出全部的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; } }