这个类很重要,是真正去容器中找出所有的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; } }