getObjectForBeanInstance这个方法是获取beanFactory加工过之后的bean实例的方法
转换beanName
这里主要是先得知道到底是要加载哪个bean。比如把别名转换为真实的bean名称,又或者说FactoryBean带的前缀。
尝试从缓存中加载单例
如果获取到进行实例化。
下面就是没获取到的情况的处理
原型模式的依赖检查
这里就是检查是否出现依赖被重复加载的地方。
也就是说一个bean在加载中还没加载完,这时候另一个bean依赖了该bean,所以导致又来加载该bean,这时候就会返回为true
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
检测parentBeanFactory
tips: 这里一个很重要的条件是!containsBeanDefinition(beanName)
当前加载的xml是没有当前加载的beanName对应的beanDefinition的时候就只能交给parentBeanFactory去递归处理了
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
xxxxxx
}
将存储XML配置文件的GernericBeanDefinition 转换为RootBeanDefinition
因为从xml配置文件中读取到的Bean信息是存储在GernericBeanDefinition中的。
但是所有的Bean后续处理都是针对于RootBeanDefinition 的,所以这里需要进行一个转换,转换的同时如果父类bean不为空的话,则会一并合并父类的属性。也就是继承的属性会在这里合并。
合并代码如下
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
寻找依赖
这里就是当前bean在初始化过程中可能需要用到某些属性,这些属性又可能是动态配置的,这个属性刚好需要依赖于其他的bean。
这时候就需要先加载依赖的bean,这时候如果需要先加载的属性刚好依赖于当前bean,那么就会抛出循环依赖异常。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
针对不同的scope 进行bean 的创建
这里会针对除了singleton的其他scope类型例如prototype、request等进行不同的处理。
类型转换
简单来说就是类型转换。将创建出的bean类型转换为参数要求要返回的类型
程序到这里返回bean后已经基本结束了,通常对该方法的调用参数requiredType是为空的,但是可能会存在这样的情况,返回的bean其实是个String,但是requiredType却传人Integer类型,那么这时候本步樂就会起作用了,它的功能是将返回的bean转换为requiredType所指定的类型。当然,String转换为Integer是最简单的一种转换,在Spring中提供了各种各样的转换器,用户也可以自己扩展转换器来满足需求。