文章目录
- 1 问题来源
- 2 bean 初始化流程
- 2.1 getBean->doGetBean->createBean
- 2.2 createBean->doCreateBean
- 2.3 doCreateBean->(createBeanInstance,populateBean,initializeBean,registerDisposableBeanIfNecessary)
- 2.4 createBeanInstance
- 2.5 populateBean
- 2.6 initializeBean
- 2.7 registerDisposableBeanIfNecessary
- 3 各种 PostProcessor 解析
- 3.1 InstantiationAwareBeanPostProcessor
- 3.2 MergedBeanDefinitionPostProcessors
- 3.3 SmartInstantiationAwareBeanPostProcessor
- 3.4 BeanPostProcessor
- 3.5 有很多后置处理器,都是主要作用在类实例化完成之后
- 4 几个 Aware 接口
- 5 循环依赖产生原因
- 5.1 有两种情况可以产生循环依赖:构造函数法、其它方法(注解注入、xml 中的 depends-on)
- 5.2 其它方法产生原因代码跟踪
- 5.3 构造函数循环依赖
- 5.4 总结
- 6 总结
- 参考
1 问题来源
spring
将 bean
的初始化和各个 bean
之间的关系交给了框架来处理,大大了简化了项目搭建的流程
- 但是在简化的同时也隐藏了
bean
之间初始化关系的流程
- 熟悉
bean
初始化的流程可以更好的把握项目运行的顺序,也能够更好的把握 spring
中的一些扩展点
2 bean 初始化流程
spring
启动的整个过程可以最简化为 两个步骤:
1)获取所有的 beanDefinition
2)遍历所有的 beanDefinition
,实例化相应的 bean
(非懒加载的 bean
)
public void refresh() {
this.invokeBeanFactoryPostProcessors(beanFactory);
this.finishBeanFactoryInitialization(beanFactory);
}
2.1 getBean->doGetBean->createBean
- 通过别名获取
beanName
- 判断缓存中是否已经存在此实例,如果有,打出相应日志
- 如果没有:按照
bean
的类型,分情况处理
- 将父类属性合并到此类中
- 递归初始化依赖类(这里是
xml
中定义的 depends-on
属性)
- 初始化该类
public Object getBean(String name, Object... args) throws BeansException {
return this.doGetBean(name, (Class)null, args, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
String[] dependsOn = mbd.getDependsOn();
if (mbd.isSingleton()) {
sharedInstance = createBean();
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
} else {
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
return convertedBean;
} else {
return bean;
}
}
2.2 createBean->doCreateBean
- 设置
override
属性
- 调用所有
InstantiationAwareBeanPostProcessor
,做一些扩展
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
mbdToUse.prepareMethodOverrides();
Object beanInstance;
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
2.3 doCreateBean->(createBeanInstance,populateBean,initializeBean,registerDisposableBeanIfNecessary)
createBeanInstance
:通过策略创建bean包装实例——这里可能回去递归初始化构造器中参数的类
- 调用所有的
MergedBeanDefinitionPostProcessors
,一个扩展点
- 提前暴露引用,允许循环引用,一般为
true
populateBean
:注入依赖类和相关属性——这里递归初始化注解的依赖类
initializeBean
:调用初始化方法
registerDisposableBeanIfNecessary
:搬到 bean
销毁的方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
Object var7 = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
2.4 createBeanInstance
- 使用适当的实例化策略为指定
bean
创建一个新实例:工厂方法、构造函数自动注入或简单的实例化。
- 详细参考链接
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
Class<?> beanClass = resolveBeanClass(mbd, beanName);
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
return instantiateBean(beanName, mbd);
}
2.5 populateBean
- 将本类的依赖类注入到类中
- 将所有
ProtertyValues
中的属性填充至本类中
- populateBean实现 依赖注入源码解析
- Spring源码:PropertyValues类及属性注入一
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (continueWithPropertyPopulation) {
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (mbd.getResolvedAutowireMode() == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
2.6 initializeBean
- 统一调用
bean.setxxxAware
;如果该类实现了某个 aware接口
的话
- 初始化之前调用,遍历所有的
beanPostProcessorsBefore
- 调用初始化方法:
afterPropertiesSet()
和 initMethod()
- 调用
BeanPostProcessorsAfter
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
this.invokeInitMethods(beanName, wrappedBean, mbd);
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2.7 registerDisposableBeanIfNecessary
- 关键在
DisposableBeanAdapter
中解析(绑定)了类的 destroy
方法
- 这样
bean
销毁时,就会调用相应的方法,对应于 initializeBean
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
3 各种 PostProcessor 解析
- 在以上分析初始化流程时,用到了各种后置处理器,统计为以下几种:
3.1 InstantiationAwareBeanPostProcessor
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {}
default boolean postProcessAfterInstantiation(Object bean, String beanName){}
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName){}
3.2 MergedBeanDefinitionPostProcessors
void postProcessMergedBeanDefinition(RootBeanDefinition var1, Class<?> var2, String var3);
default void resetBeanDefinition(String beanName) {}
3.3 SmartInstantiationAwareBeanPostProcessor
default Class<?> predictBeanType(Class<?> beanClass, String beanName){}
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName){}
default Object getEarlyBeanReference(Object bean, String beanName){}
3.4 BeanPostProcessor
default Object postProcessBeforeInitialization(Object bean, String beanName){}
default Object postProcessAfterInitialization(Object bean, String beanName){}
- 在
DataSourceAutoConfiguration
中就注册了一个 DataSourceInitializerPostProcessor
class DataSourceInitializerPostProcessor implements BeanPostProcessor, Ordered {
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DataSource) {
this.beanFactory.getBean(DataSourceInitializerInvoker.class);
}
return bean;
}
}
3.5 有很多后置处理器,都是主要作用在类实例化完成之后
- 类中用注解声明的属性,比如@PostConstruct、@Resource、@Autowired、@Value、@Required、@AspectJ、@Valid、@Scheduled、@ Async等等注解,都是通过注册后置处理器来扩展的。
4 几个 Aware 接口
- 在
initializeBean()
方法最开始,就调用了 invokeAwareMethods
,用来处理类是否实现了几个 Aware
接口
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
5 循环依赖产生原因
5.1 有两种情况可以产生循环依赖:构造函数法、其它方法(注解注入、xml 中的 depends-on)
5.2 其它方法产生原因代码跟踪
- 如项目中所示:
ClassA
关联 ClassB
,ClassB
关联 ClassC
,ClassC
关联 ClassA
- 这样初始化任何一个类的时候,都会递归去初始化关联类,导致循环依赖
- 总结: 关联依赖,能够成功初始化的原因在于,在递归初始化关联类之前,已经把本类的引用给暴露出去了,这样关联类完全可以只先指向它的引用,而先不用关心这个引用到底有没有执行完全
getBean(beanName){}
doGetBean(beanName){
Object sharedInstance = this.getSingleton(beanName);
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
String[] dependsOn = mbd.getDependsOn();
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
if (bp instanceof InstantiationAwareBeanPostProcessor) {
ibp.postProcessProperties();
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
- 总结: 关联依赖,能够成功初始化的原因在于,在递归初始化关联类之前,已经把本类的引用给暴露出去了,这样关联类完全可以只先指向它的引用,而先不用关心这个引用到底有没有执行完全
5.3 构造函数循环依赖
- 构造函数循环依赖肯定是直接报错的
- 因为解决循环依赖的关键在于,提前把本类的引用暴露出去
- 而提前暴露出去的前提是:已经实例化了(
new
了某个构造器了)
- 而构造函数循环依赖,是在实例化本类之前,要得到依赖类,所以本类不可能有引用
5.4 总结
- 任何形成循环依赖的配置方法,如果是在实例化本类之后,在递归实例化依赖类,就不会报错,因为本类的引用已经暴露了,如:注解依赖
- 如果在实例化本类之前,递归实例化依赖类,则会报错,如:构造函数依赖,
xml depends-on
依赖等
6 总结
bean
初始化的过程细节很多,初期的时候把握一个大概流程即可,不然很有可能看蒙
- 把握整体之后,如果有兴趣或者项目需要,可以慢慢深入
参考
- 深入理解spring生命周期与BeanPostProcessor的实现原理
- 依赖注入之Bean实例化前的准备
- BeanPostProcessor接口
- populateBean实现 依赖注入源码解析
- Spring源码:bean创建(三):createBeanInstance
- Springboot 源码分析—— 总纲
- Springboot 源码分析—— prepareEnvironment() 解析
- Springboot 源码分析—— refreshContext() 解析
- Springboot 2.1.1.RELEASE