您的位置:首页 > 编程语言 > Java开发

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

2016-12-27 00:00 344 查看
摘要: 学习spring都听过ioc这个词,getBean方法里面就是IOC工作的地方。

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);
}
}
3ff0
//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;
}


先把传人的name转变成真实的对象名称beanName: 传人的name称可能是别名或者工厂名(工厂名前缀为&)

用beanName到缓存里获取单例对象,如果为空则走下面流程,这步是针对单例对象的,这里有三层缓存(为了解决循环依赖,后面单独叙述,这里主要看主流程,否则会绕进去)。

原型依赖检查,循环依赖只有在单例情况下可用,原型情况下向上抛异常

如果BeanDefinitionMap中没有对应的bean,则到parentBeanFactory去寻找

如果上面都没获取到对象,则用beanName获取BeanDefinition转成RootBeanDefinition对象,后面不同类型的scope都是根据RootBeanDefinition创建的。

先创建BeanDefinition的dependsON对象(bean标签的depends-on属性,depends-on标签不能循环依赖)

根据bean的scope走不同的创建流程,针对不同scope做了不同的控制,比如:singleton模式通过getSingleton方法,这个里面创建对象时会先校验缓存是否已经存在该对象,prototype模式直接创建对象,其他类型的则可以通过自定义Scope来实现逻辑控制,设想一下如果把对象放到第三方缓存中则可在这边自定义一个Scope。最终bean的构造委托给了createBean,createBean方法比较复杂,下面单独看。

上面获取到的对象最终都需要再次校验一下,因为获取的对象也可能是个工厂,这里校验的方法就是getObjectForBeanInstance

用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;
}

这里分为三个核心过程:

先创建bean,

然后把填充bean的属性,这个里面就是解析了依赖对象,

最后调用initializeBean初始化bean.

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring ioc getbean