spring创建Bean得过程非常复杂,本文将分段进行解析,尽量阐述更加清晰
1、finishBeanFactoryInitialization(beanFactory);
spring创建得单实例对象,大部分是在这个方法里面进行创建的
根据最后一行代码可知,其作用是实例化所有的非懒加载的单例对象
2、循环遍历beanDefinitionNames
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames;
synchronized (this.beanDefinitionMap) {
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
//beanDefinitionNames就是之前文章中加载beanDefinitions时期就把所有符合的定义信息放入了beanFactory
for (String beanName : beanNames) {
//从本地缓存获取bean的定义信息,如果没有就从beanDefinitionMap中取,beanDefinitionMap之前文章有说过
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
//工厂bean的创建逻辑
...
}else {
//非工厂bean的创建逻辑
getBean(beanName);
}
}
}
}
2.1、getMergedBeanDefinition
获取合并的bean的定义信息,该方法在AbstractBeanFactory中,主要作用就是将bean的定义信息放入本地缓存中
2.2、getBean(beanName);根据bean的name获取bean对象实例
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
进入doGetBean方法,本文将doGetBean方法分段就行讲解
第一部分:getSingleton(beanName)
根据名称获取对象,主要就是想从缓存中获取对象,进入代码
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
singletonObjects是一个map,并且是spring用于解决依赖注入的一级缓存,前期的一些后置处理器已经创建完毕,在这个一级缓存中已经存在了对象信息
getSingleton如果返回了对象,则进行判断是不是工厂bean类型,如果不是直接返回对象,如果是工厂类型的则使用工厂bean方式获取对象
第二部分:getSingleton(String beanName, ObjectFactory<?> singletonFactory)
图1
此时将进行第一次单实例对象的创建,我们看到用到了工厂bean的形式
图2
接图2尾巴
回调getObject时进入createBean流程(见图1),继续调用 Object beanInstance = doCreateBean(beanName, mbd, args);执行完createBeanInstance方法后,对象创建完成
图3
对象创建后开始应用后置处理器(准确说是应用MergedBeanDefinitionPostProcessor类型的后置处理器)
图4
图5
关注AutowiredAnnotationBeanPostProcessor后置处理器,主要处理@Autowired注解的
图6
找到了当前对象的一个被@Autowired注解标注的属性
图7
doCreateBean方法继续向下走
图8
doCreateBean方法继续向下走
图9
进入populateBean属性封装方法,再一次进行后置处理器操作(准确的说是InstantiationAwareBeanPostProcessor类型的后置处理器)
图10
重点关注AutowiredWiredAnnotationBeanPostProcessor
图11
重点:再一次调用了这个后置处理器,之前已经调用过一次,所以这次findAutowiringMetadata这个方法获取元数据会走缓存
图12
构建元数据的方法也很简单,通过反射获取属性
图13
回到AutowiredWiredAnnotationBeanPostProcessor的方法调用(见图11)
此时调用metadata.inject元数据注入,
进入element.inject
进入findAutowireCandidates方法
重点关注两个方法,图中标注
进入方法1:
图14
图15
遍历循环所有的bean定义信息名称数组,找到匹配当前对象属性类型的bean名称
获取bean的定义信息和之前一样,都是系统中已经存在的bean的定义信息
继续看上图的doGetBeanNamesForType方法,会把符合类型的bean的name放入result返回到图15最后到图14
进入方法2(图14上面)
此时要给当前对象的属性进行创建对象,创建完成后进入当前对象的属性赋值方法,回到图9,给当前对象设置属性信息
属性赋值完成后进行initializeBean初始化对象,初始化前后会又有处理器进行工作,其中初始化方法需要实现当前类实现InitializingBean接口才会有哦
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
...
}
else {
//调用aware类型的后置处理器
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用后置处理器的beforeInit...方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用对象的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//调用对象的afterInit...方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
总结
文章可能比较长,但是如果能一点点跟进,会对自己认识spring创建对象有很大的帮助,最后对于spring循环依赖,简单的说下,其实如果一点点跟进,会发现spring三级缓存处理循环依赖特别清晰,三级缓存就是三个map,对象刚开始创建的时候会先放到singletonFactories这个map,如果对象A有属性B,会在属性封装前创建属性B对象也放入了singletonFactories这个map,当这个属性B对象又依赖了这个对象A时,B在属性封装时会去getBean创建A,此时 看如下代码,对象A会被放入了earlySingletonObjects这个map,并且从singletonFactories去除,对象在最终创建完成后会进行addSingleton操作(见接图2尾巴),放入singletonObjects这个map
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}