Spring之getBean

总体流程

protected <T> T doGetBean(
		final String name, final Class<T> 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 instance
    Map<String, Object> 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<Object>() {
		@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<Exception>();
		}
		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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值