博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring之getBean
阅读量:7070 次
发布时间:2019-06-28

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

  hot3.png

总体流程

protected 
T doGetBean( final String name, final Class
requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 1、转换beanName final String beanName = transformedBeanName(name); Object bean; // 2、获取缓存中的singleton类型的实例,也有可能是提早暴露的没有完全初始化的实例 // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) {// singleton类型的bean,args必须是null,否则报错 2.1 } else { 2.2 } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { 3 } return (T) bean;}

1、处理beanName

2、获取缓存中的singleton类型的实例,这里有两种情况:

  • 已经初始化完成的bean实例,从singletonObjects中获取
    bean name --> bean instanceMap
    singletonObjects
  • 提早暴露的正在创建中的bean,没有完全初始化的bean(这个是用来解决循环依赖)

 

2.1、getSingleton(beanName) 不为空

PS:getBean()的参数arg在singleton类型的bean时必须为null,否则报错。

if (logger.isDebugEnabled()) {	if (isSingletonCurrentlyInCreation(beanName)) {		logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +				"' that is not fully initialized yet - a consequence of a circular reference");	}	else {		logger.debug("Returning cached instance of singleton bean '" + beanName + "'");	}}// 处理FactoryBean类型bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

2.2、getSingleton(beanName)为空

1、检查prototype类型的bean,如果是循环依赖就报错

if (isPrototypeCurrentlyInCreation(beanName)) {	throw new BeanCurrentlyInCreationException(beanName);}

2、如果当前找不到当前bean的BeanDefinition,就从父类BeanFactory中获取

// Check if bean definition exists in this factory.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {	// Not found -> check parent.	String nameToLookup = originalBeanName(name);	if (args != null) {		// Delegation to parent with explicit args.		return (T) parentBeanFactory.getBean(nameToLookup, args);	}	else {		// No args -> delegate to standard getBean method.		return parentBeanFactory.getBean(nameToLookup, requiredType);	}}

3、获取BeanDefinition

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 如果是singleton类型的bean,args不为null就报错checkMergedBeanDefinition(mbd, beanName, args);

4、处理singleton类型的创建

// Create bean instance.if (mbd.isSingleton()) {	sharedInstance = getSingleton(beanName, new ObjectFactory() {		@Override		public Object getObject() throws BeansException {			try {				return createBean(beanName, mbd, args);			}			catch (BeansException ex) {				// Explicitly remove instance from singleton cache: It might have been put there				// eagerly by the creation process, to allow for circular reference resolution.				// Also remove any beans that received a temporary reference to the bean.				destroySingleton(beanName);				throw ex;			}		}	});    // 处理FactoryBean	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}

通过getSingleton()方法,传入ObjectFactory的匿名实现。

4.1、getSingleton()

Assert.notNull(beanName, "'beanName' must not be null");synchronized (this.singletonObjects) {	Object singletonObject = this.singletonObjects.get(beanName);	if (singletonObject == null) {		...		beforeSingletonCreation(beanName);		boolean newSingleton = false;		boolean recordSuppressedExceptions = (this.suppressedExceptions == null);		if (recordSuppressedExceptions) {			this.suppressedExceptions = new LinkedHashSet
(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } ... finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null);}

总体分为这几步:

  1. beforeSingletonCreation:将beanName加入到正在创建的集合中
  2. singletonFactory.getObject():调用之前传入的ObjectFactory实现,进入创建bean的流程n
  3. afterSingletonCreation:将beanName从正在创建的集合中移除
  4. addSingleton:加入到缓存中

5、其他类型的不看了

3、对bean类型转换

// Check if required type matches the type of the actual bean instance.if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {	try {		return getTypeConverter().convertIfNecessary(bean, requiredType);	}	catch (TypeMismatchException ex) {		if (logger.isDebugEnabled()) {			logger.debug("Failed to convert bean '" + name + "' to required type [" +					ClassUtils.getQualifiedName(requiredType) + "]", ex);		}		throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());	}}return (T) bean;

 

转载于:https://my.oschina.net/cregu/blog/3033218

你可能感兴趣的文章
高通470亿美元收购恩智浦获反垄断机构许可
查看>>
360搜索回归360母品牌 安全搜索才“靠谱”
查看>>
《stm32嵌入式系统开发实战指南》一1.2 Cortex内核系列处理器技术特点
查看>>
干掉APT的是人 不是技术
查看>>
苹果确认iOS 10存在安全漏洞
查看>>
江西推进11个 全国智慧城市试点
查看>>
云通信初创企业Twilio启动IPO Uber和Airbnb均是其客户
查看>>
为什么发展中国家更关注智慧城市?
查看>>
W3C准备将DRM定为Web标准
查看>>
神秘数据挖掘独角兽Palantir说准备好要上市,但明年盈利的豪言有点虚
查看>>
全球3600万部安卓设备遭“Judy”恶意软件入侵
查看>>
Redis持久存储-AOF&RDB
查看>>
存储已向云上转移 平台化存储更加灵活
查看>>
ONF执行主席Dan Pitt:下一个战争可能是控制器
查看>>
引狼入室,给中国云市场引来了什么?
查看>>
360强力卸载能不能卸载360?我们从360美国退市说起
查看>>
如何避开采购黑幕 高效透明地进行招投标管理?
查看>>
IBM InterConnect大会开幕:发布多项新服务与新功能
查看>>
创业公司全年IT基础设施费用竟仅需六千元!
查看>>
iOS 11 iMessage增加了两个新的屏幕效果
查看>>