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
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
初始化的过程细节很多,初期的时候把握一个大概流程即可,不然很有可能看蒙把握整体之后,如果有兴趣或者项目需要,可以慢慢深入
参考