Instantiate all remaining (non-lazy-init) singletons.
初始化剩下非懒加载的实例对象
finishBeanFactoryInitialization方法第918行,beanFactory.preInstantiateSingletons();
preInstantiateSingletons方法,遍历beanDefinitionNames,通过mergedBeanDefinitions来获取每一个RootBeanDefinition,并判断他是否是factorybean,如果不是,调用getBean()方法。如果是,看到后面的FactoryBean部分
doGetBean方法
第252行,transformedBeanName(name),用于返回真实beanName,如果是beanName以&开头(表示factoryBean),去掉&并返回。通过Map
第256行,getSingleton(beanName),通过singletonObjects来获取之前是否已经注入到IOC中
Eagerly check singleton cache for manually registered singletons.
在这里面做了三级缓存,也是spring解决循环依赖的地方,在后面分析
这里做调试的类没有进行过初始化,singletonObjects返回null
AbstractBeanFactory第300行,typeCheckOnly一般都为false(用于类型检查实例是否获得,而不是实际使用)
进入markBeanAsCreated方法
判断alreadyCreated(已标记为创建)是否包含beanName,这里通过双重校验锁,如果不包含,将beanName添加到alreadyCreated
clearMergedBeanDefinition方法,将bd的stale设置为true,并从mergedBeanDefinitionHolders移除beanName
AbstractBeanFactory第309行,getMergedLocalBeanDefinition方法
进入getMergedLocalBeanDefinition方法
从mergedBeanDefinitions取出beanName对应的RootBeanDefinition
回到AbstractBeanFactory,判断类是否有@DependsOn注解
第332行,开始创建对象实例
进入getSingleton方法
通过双重校验再次判断singletonObjects是否存在beanName
第234行,开始调用ObjectFactory(类似Supplier)的getObject方法
第514行,resolveBeanClass,解析beanClass,如果是对象被代理,返回代理对象的class
第531行,resolveBeforeInstantiation,如果有自定义InstantiationAwareBeanPostProcessor实现,调用postProcessBeforeInstantiation(实例化之前执行)。可以实例化自定义bean,但是这个回调会在所有bean实例化的时候都执行。非自定义的类也会在这里实例化,会有不可预估的风险,如果方法返回的不为null,表示已经实例化,直接返回这个bean作为创建的单例对象,并注册到IOC容器。
Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
第542行,doCreateBean,正式开始实例化bean
determineConstructorsFromBeanPostProcessors,在这里回调SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,可以用来设置类的自定义构造器
instantiateBean方法,通过默认无参构造来实例化bean
进入instantiateBean方法,第1326行。beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
通过实例化策略执行器开始实例化bean,主要还是通过构造器实例化,过程略。
返回实例对象后,封装成BeanWrapper并返回
实例化bean之后,第594行,applyMergedBeanDefinitionPostProcessors方法。会在这里回调MergedBeanDefinitionPostProcessor接口postProcessMergedBeanDefinition方法
进入populateBean方法,第1399行,回调InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation。用于自定义判断bean与beanName是否满足相同预期结果
第1431行,回调InstantiationAwareBeanPostProcessor接口的postProcessProperties方法
这里有一个spring的实现类AutowiredAnnotationBeanPostProcessor,这里会根据进行@Autowire注解的依赖注入,会实例化依赖的类
依然会通过beanFactory.getBean(beanName);来实例化依赖的类
进入initializeBean,第1791行,invokeAwareMethods
判断bean是否实现Aware,如果当前对象是cglib生成的代理对象,默认实现EnhancedConfiguration接口,该接口继承了BeanFactoryAware
把beanFactory设置到bean中
在这里执行BeanPostProcessor接口的postProcessBeforeInitialization回调
InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization,会触发bean的@PostConstruct注解方法(充当init-method)
ConfigurationPropertiesBindingPostProcessor的postProcessBeforeInitialization,会执行@ConfigurationProperties的自定绑定model字段逻辑。
判断类上是否有@ConfigurationProperties,并创建ConfigurationPropertiesBean返回
获取待绑定的字段,从PropertySource中寻找该字段对应的值(PropertySource值在之前已经缓存)
最终通过JavaBeanBinder的setValue方法,来为字段赋值
会回调InitializingBean接口的afterPropertiesSet
如果对象有初始化方法(在其他配置类中定义的@Bean(initMethod = “doInit”)),会进行调用
调用BeanPostProcessor的postProcessAfterInitialization方法
上面已经将对象实例化。
第633行,getSingleton方法。
第661行,registerDisposableBeanIfNecessary方法。
待补充
遍历所有容器单例对象,判断是否实现SmartInitializingSingleton,如果实现会调用afterSingletonsInstantiated方法
至此finishBeanFactoryInitialization结束
前提:开启允许循环依赖,springboot 2.6 之后就默认关闭了。
A(cicA)与B(cicB)相互依赖,A先进行初始化
判断是否开启了循环依赖,并添加A的bean实例工厂到beanFactory的singletonFactories中(作为第三级缓存)
在populateBean方法中,回调InstantiationAwareBeanPostProcessor的postProcessProperties方法。这里我们需要关注AutowiredAnnotationBeanPostProcessor类。执行依赖注入
通过A上被@Autowire修饰的成员变量,获取到待注入的类(这里的cicB是与当前类互为循环依赖的),封装成InjectedElement
遍历这两个InjectedElement,依次进行解析,并调用beanFactory.getBean(beanName)。这里的bean是cicB
B完成bean实例创建,和A的第1步一样
添加B的bean实例工厂到beanFactory的singletonFactories中,和A的第2步一样
依然通过AutowiredAnnotationBeanPostProcessor的postProcessProperties方法,获取B下的被@Autowire修饰的成员变量,来执行依赖注入
和A的第3步一样,调用beanFactory.getBean(beanName)。这里的bean是cicA
来到doGetBean的getSingleton(beanName)方法,从这里尝试获取A的对象
a. 首先从一级缓存singletonObjects获取bean,因为A对象只是实例化,还没有初始化,因此还没有注入到singletonObjects中
b.一级缓存中获取不到bean,从二级缓存earlySingletonObjects获取,此时二级缓存也没有A的对象
c. 这里通过双重校验锁再次确保一、二级缓存都不存在bean。从三级缓存singletonFactories中获取到对象的ObjectFactory,通过执行ObjectFactory.getObject方法。调用如下的函数式接口,beanName为cicA,bean为实例化之后的cicA对象,返回该对象
这里会调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
返回cicA对象,将对象放入二级缓存earlySingletonObjects中
获取到cicA之后,通过Field将cicA设置到cicB的字段中
cicB完成初始化,注册到一级缓存,从二、三级缓存删除
用于创建比较复杂的bean
比如从配置文件中获取配置,通过不同值来生成不同bean
package org.hopehomi.boot.model.factorybean;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
* @author Ledison
* @date 2023/3/19
*/
@Component
@Slf4j
@Data
public class MyFactoryBean implements SmartFactoryBean<Human>, InitializingBean, DisposableBean {
private Human human;
@Autowired
private Environment environment;
public MyFactoryBean() {
System.out.println("MyFactoryBean construct");
}
@Override
public boolean isEagerInit() {
return true;
}
@Override
public void afterPropertiesSet() throws Exception {
String sex = environment.getProperty("sex");
if (sex.equals("1")) {
human = new Man();
} else {
human = new Woman();
}
}
@Override
public Human getObject() throws Exception {
return human;
}
@Override
public Class<?> getObjectType() {
return Human.class;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public void destroy() throws Exception {
System.out.println("MyFactoryBean (DisposableBean) destroy");
}
}
在使用中根据beanFactory的beanName来获取对象,取到的是getObject的对象。和根据bean类获取到的对象相同
如果需要获取原始Factorybean对象,需要在Factorybean前加&
preInstantiateSingletons方法,判断bean为FactoryBean
过程与前面非FactoryBean大致相同,直接来到docreateBean
这里会从factoryBeanInstanceCache中获取beanName的BeanWrapper。
这个缓存是在registerBeanPostProcessors(beanFactory)的过程中就实例化了FactoryBean对象并添加到缓存中,源码略
BeanWrapper不为null,就不会在这进行实例化,后面的逻辑也和普通bean相同,依赖注入、调用初始化方法
获取到FactoryBean的实例
如果FactoryBean实现了SmartFactoryBean且isEagerInit为true,会在这里更早进行初始化代理对象。
注意这里的beanName前面没有加&
先判断是否name以&开头,如果以&开头,表示是FactoryBean的本体name
那么直接返回本体对象
如果不是以&开头,从IOC容器获取到了FactoryBean的实例,调用getObjectFromFactoryBean方法来获取代理对象
这里调用FactoryBean的getObject方法,用来返回自定义代理实例
将代理对象放入factoryBeanObjectCache。下次再执行getBean会直接从factoryBeanObjectCache中返回对象。