Spring源码阅读-BeanFactory-对象创建过程

原创
2016/12/27 20:21
阅读数 548

1 getBean

上一节只是加载配置,并把文件内容映射到BeanDefinition中,真正的创建对象跟依赖注入是在getBean中处理的,这里实际上就是根据BeanDefinition用反射创建对象及其依赖对象,只不过spring里面处理的比较复杂,这里面的每一步都有很多逻辑处理,并且在这前后做了很多的异常的判断校验。

还是以XmlBeanFactory跟踪代码看一下getBean流程,最终进入到AbstractBeanFactory的doGetBean方法:

protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args,
		boolean typeCheckOnly) throws BeansException {
	//1 去掉工厂bean的前缀& 并找到alias对应的名称
	final String beanName = transformedBeanName(name);
	Object bean;
	// Eagerly check singleton cache for manually registered singletons.
	//2 先从缓存中获取
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == 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 + "'");
			}
		}
		//如果是bean工厂,则创建对象
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	else {
		// Fail if we're already creating this bean instance: We're assumably within a circular reference.
		//3 在原形情况下创建循环依赖就会报错
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		//4 Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		//如果存在父bean工厂并且没有配置该bean,则从父bean工厂创建
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			//递归调用getBean
			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);
			}
		}
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}
		try {
			//5 转换BeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			//6 depends-on标签
			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					if (isDependent(beanName, dependsOnBean)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean
										+ "'");
					}
					registerDependentBean(dependsOnBean, beanName);
					//递归调用
					getBean(dependsOnBean);
				}
			}
			//7 不同scope情况下创建对象
			// Singleton情况
			// Create bean instance.
			if (mbd.isSingleton()) {
				//getSingleton有单例的控制, 防止前面已经创建过该对象,如果没创建过该对象最终也是调用createBean
				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;
						}
					}
				});
				//8 获取最终的对象
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
			//prototype情况
			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				} finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			//其他情况
			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							} finally {
								afterPrototypeCreation(beanName);
							}
						}
					});
					bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				} catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; "
									+ "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		} catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}
	//9 类型转换
	// 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;
}
  1. 先把传人的name转变成真实的对象名称beanName: 传人的name称可能是别名或者工厂名(工厂名前缀为&)
  2. 用beanName到缓存里获取单例对象,如果为空则走下面流程,这步是针对单例对象的,这里有三层缓存(为了解决循环依赖,后面单独叙述,这里主要看主流程,否则会绕进去)。
  3. 原型依赖检查,循环依赖只有在单例情况下可用,原型情况下向上抛异常
  4. 如果BeanDefinitionMap中没有对应的bean,则到parentBeanFactory去寻找
  5. 如果上面都没获取到对象,则用beanName获取BeanDefinition转成RootBeanDefinition对象,后面不同类型的scope都是根据RootBeanDefinition创建的。
  6. 先创建BeanDefinition的dependsON对象(bean标签的depends-on属性,depends-on标签不能循环依赖)
  7. 根据bean的scope走不同的创建流程,针对不同scope做了不同的控制,比如:singleton模式通过getSingleton方法,这个里面创建对象时会先校验缓存是否已经存在该对象,prototype模式直接创建对象,其他类型的则可以通过自定义Scope来实现逻辑控制,设想一下如果把对象放到第三方缓存中则可在这边自定义一个Scope。最终bean的构造委托给了createBean,createBean方法比较复杂,下面单独看。
  8. 上面获取到的对象最终都需要再次校验一下,因为获取的对象也可能是个工厂,这里校验的方法就是getObjectForBeanInstance
  9. 用TypeConverter转成最终需要的类型。

时序图如下:

2 createBean

上面第7步,创建对象委托给了createBean,createBean中做一下初始化确认就把创建对象委托给了doCreateBean,doCreateBean核心代码如下:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		//1. 创建对象
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

	//...省略

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		//2. 填充对象   这个里面解析了依赖的bean
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			//3. 初始化方法
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
	} catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		} else {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed",
					ex);
		}
	}

	//...省略

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	} catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature",
				ex);
	}

	return exposedObject;
}

这里分为三个核心过程:

  1. 先创建bean,
  2. 然后把填充bean的属性,这个里面就是解析了依赖对象,
  3. 最后调用initializeBean初始化bean.

这三部分里面都比较复杂,后面有时间再看,看一下createBean的时序图:

展开阅读全文
加载中

作者的其它热门文章

打赏
0
1 收藏
分享
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部