Spring源码 19 IOC getBean方法

前面实现了 ClassPathXmlApplicationContext 的构造,接下来分析其调用的 getBean 方法。
getBean(UserDao.class) 为例。

1 AbstractApplicationContext

public <T> T getBean(Class<T> requiredType) throws BeansException {
    // 断言 Bean 工厂活动
    assertBeanFactoryActive();
    // 获取 Bean 工厂
    // 获取 Bean
    return getBeanFactory().getBean(requiredType);
}

1-1 断言 Bean 工厂活动

assertBeanFactoryActive()
protected void assertBeanFactoryActive() {
   if (!this.active.get()) {
      if (this.closed.get()) {
         // 获取显示名称
         throw new IllegalStateException(getDisplayName() + " has been closed already");
      }
      else {
         // 获取显示名称
         throw new IllegalStateException(getDisplayName() + " has not been refreshed yet");
      }
   }
}

获取显示名称前面已经分析过了,这里不再分析。

1-1 获取 Bean 工厂

getBeanFactory()

2 AbstractRefreshableApplicationContext

public final ConfigurableListableBeanFactory getBeanFactory() {
   DefaultListableBeanFactory beanFactory = this.beanFactory;
   if (beanFactory == null) {
      throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext");
   }
   return beanFactory;
}

if (beanFactory == null) 由于前面定义了 beanFactory,这里直接返回。

1 AbstractApplicationContext

1-1 获取 Bean

getBean(requiredType)

3 DefaultListableBeanFactory

public <T> T getBean(Class<T> requiredType) throws BeansException {
   // 获取 Bean
   return getBean(requiredType, (Object[]) null);
}
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
   Assert.notNull(requiredType, "Required type must not be null");
   // 解析 Bean
   Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
   if (resolved == null) {
      throw new NoSuchBeanDefinitionException(requiredType);
   }
   return (T) resolved;
}

3-1 解析 Bean

resolveBean(ResolvableType.forRawClass(requiredType), args, false)
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
    // 解析 Bean 命名
    NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    }
    // 获取父级 Bean 工厂
    BeanFactory parent = getParentBeanFactory();
    if (parent instanceof DefaultListableBeanFactory) {
        // 解析 Bean,递归调用
        return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
    }
    else if (parent != null) {
        ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
        if (args != null) {
            return parentProvider.getObject(args);
        }
        else {
            return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
        }
    }
    return null;
}

3-2 解析 Bean 命名

resolveNamedBean(requiredType, args, nonUniqueAsNull)
private <T> NamedBeanHolder<T> resolveNamedBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
   Assert.notNull(requiredType, "Required type must not be null");
   // 获取类型的 Bean 名称
   String[] candidateNames = getBeanNamesForType(requiredType);
   if (candidateNames.length > 1) {
      List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
      for (String beanName : candidateNames) {
         if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
            autowireCandidates.add(beanName);
         }
      }
      if (!autowireCandidates.isEmpty()) {
         candidateNames = StringUtils.toStringArray(autowireCandidates);
      }
   }
   if (candidateNames.length == 1) {
      // 解析 Bean 命名
      return resolveNamedBean(candidateNames[0], requiredType, args);
   } else if (candidateNames.length > 1) {
      Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length);
      for (String beanName : candidateNames) {
         if (containsSingleton(beanName) && args == null) {
            Object beanInstance = getBean(beanName);
            candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
         } else {
            candidates.put(beanName, getType(beanName));
         }
      }
      // 确定主要候选
      String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
      if (candidateName == null) {
         // 确定最高优先级候选
         candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
      }
      if (candidateName != null) {
         Object beanInstance = candidates.get(candidateName);
         if (beanInstance == null) {
            return null;
         }
         if (beanInstance instanceof Class) {
            // 解析 Bean 命名
            return resolveNamedBean(candidateName, requiredType, args);
         }
         return new NamedBeanHolder<>(candidateName, (T) beanInstance);
      }
      if (!nonUniqueAsNull) {
         throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
      }
   }
   return null;
}

3-3 确定主要候选

determinePrimaryCandidate(candidates, requiredType.toClass())
protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
   String primaryBeanName = null;
   for (Map.Entry<String, Object> entry : candidates.entrySet()) {
      String candidateBeanName = entry.getKey();
      Object beanInstance = entry.getValue();
      if (isPrimary(candidateBeanName, beanInstance)) {
         if (primaryBeanName != null) {
            boolean candidateLocal = containsBeanDefinition(candidateBeanName);
            boolean primaryLocal = containsBeanDefinition(primaryBeanName);
            if (candidateLocal && primaryLocal) {
               throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one 'primary' bean found among candidates: " + candidates.keySet());
            } else if (candidateLocal) {
               primaryBeanName = candidateBeanName;
            }
         } else {
            primaryBeanName = candidateBeanName;
         }
      }
   }
   return primaryBeanName;
}

3-3 确定最高优先级候选

determineHighestPriorityCandidate(candidates, requiredType.toClass())
protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
   String highestPriorityBeanName = null;
   Integer highestPriority = null;
   for (Map.Entry<String, Object> entry : candidates.entrySet()) {
      String candidateBeanName = entry.getKey();
      Object beanInstance = entry.getValue();
      if (beanInstance != null) {
         Integer candidatePriority = getPriority(beanInstance);
         if (candidatePriority != null) {
            if (highestPriorityBeanName != null) {
               if (candidatePriority.equals(highestPriority)) {
                  throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "Multiple beans found with the same priority ('" + highestPriority + "') among candidates: " + candidates.keySet());
               } else if (candidatePriority < highestPriority) {
                  highestPriorityBeanName = candidateBeanName;
                  highestPriority = candidatePriority;
               }
            } else {
               highestPriorityBeanName = candidateBeanName;
               highestPriority = candidatePriority;
            }
         }
      }
   }
   return highestPriorityBeanName;
}

参考

https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0

《Spring源码深度解析(第2版)》

版本

Spring 5.3.15

posted @ 2022-03-14 14:02  天航星  阅读(67)  评论(0编辑  收藏  举报