参考源
《Spring源码深度解析(第2版)》
版本
本文章基于 Spring 5.3.15
前面实现了
以ClassPathXmlApplicationContext
的构造,接下来分析其调用的getBean
方法。getBean(UserDao.class)
为例。
1 AbstractApplicationContext
publicT getBean(Class 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
publicT getBean(Class requiredType) throws BeansException { // 获取 Bean return getBean(requiredType, (Object[]) null);}
publicT getBean(Class 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)
privateT resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) { // 解析 Bean 命名 NamedBeanHolder 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 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)
privateNamedBeanHolder 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 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 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(Mapcandidates, Class requiredType) { String primaryBeanName = null; for (Map.Entry 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(Mapcandidates, Class requiredType) { String highestPriorityBeanName = null; Integer highestPriority = null; for (Map.Entry 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;}