博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码 19 IOC getBean
阅读量:37225 次
发布时间:2020-08-01

本文共 7503 字,大约阅读时间需要 25 分钟。

参考源

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

版本

本文章基于 Spring 5.3.15


前面实现了 ClassPathXmlApplicationContext 的构造,接下来分析其调用的 getBean 方法。

getBean(UserDao.class) 为例。

1 AbstractApplicationContext

public 
T 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

public 
T getBean(Class
requiredType) throws BeansException { // 获取 Bean return getBean(requiredType, (Object[]) null);}
public 
T 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)
private 
T 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)
private 
NamedBeanHolder
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(Map
candidates, 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(Map
candidates, 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;}

转载地址:http://uypwwy.baihongyu.com/

你可能感兴趣的文章
Visual Studio我常用的快捷键
查看>>
写C# dll供Unity调用
查看>>
Linux制作run安装包
查看>>
一分钟学会C#解析XML
查看>>
unity AssetBundle的资源管理
查看>>
【转】Unity中HideInInspector和SerializeField一起使用
查看>>
单例模板类
查看>>
Unity与java相互调用
查看>>
android截屏代码
查看>>
unity NGUI图文混排
查看>>
Unity项目优化
查看>>
Unity3D Shader 入门
查看>>
MSDK手Q邀请透传参数问题:url编解码与base64编解码
查看>>
Unity中C#如何执行cmd命令(System.Diagnostics.Process的使用)
查看>>
C#用正则表达式去匹配被双引号包起来的中文
查看>>
lua table排序
查看>>
Unity发布的ios包在iphone上声音是从听筒里出来的问题
查看>>
UIScrollView复用节点示例
查看>>
Unity 5 AudioMixer
查看>>
Unity 代码混淆: CodeGuard的使用
查看>>