一、学习指引 你了解过从Spring IOC容器中获取Bean的过程吗?
学习过Spring的小伙伴都知道:如果是单实例Bean,则IOC容器启动时,就会创建Bean对象,IOC容器关闭时,销毁Bean对象。如果是多实例Bean,IOC容器在启动时,不会创建Bean对象,在每次从IOC容器中获取Bean对象时,都会创建新的Bean对象返回,IOC容器关闭时,也不会销毁对象。也就是说,如果是多实例Bean,IOC容器不会管理Bean对象。
那从IOC容器中获取Bean的具体过程是怎样的呢?想深度学习Spring源码的小伙伴继续往下看。
二、测试案例 整个调试Spring6.0源码的案例玩玩儿呗?
本章的案例比较简单,只是实现一个用于调试源码的小案例,具体的实现步骤如下所示。
(1)创建配置类BeanConfig
BeanConfig类的源码详见:spring-annotation-chapter-04工程下的io.binghe.spring.annotation.chapter04.config.BeanConfig。
复制 @Configuration
@ComponentScan( basePackages = "io.binghe.spring.annotation.chapter04" )
public class BeanConfig {
}
可以看到,在BeanConfig类上标注了@Configuration注解,说明BeanConfig类是Spring的配置类,使用@ComponentScan注解标注了扫描的包是io.binghe.spring.annotation.chapter04。
(2)创建测试类BeanTest
BeanTest类的源码详见:spring-annotation-chapter-04工程下的io.binghe.spring.annotation.chapter04.BeanTest。
复制 public class BeanTest {
public static void main( String[ ] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( BeanConfig.class ) ;
context.close ( ) ;
}
}
可以看到,在BeanTest类中只是简单的使用AnnotationConfigApplicationContext类创建IOC容器,并关闭IOC容器。
好了,测试案例准备好了,接下来,就一步步分析从IOC容器中获取Bean的过程。
三、源码时序图 结合时序图理解源码会事半功倍,你觉得呢?
其实,经过前面章节的学习,细心的小伙伴在调试Spring源码的过程中会发现,在Spring的AbstractApplicationContext类中的refresh()方法中,会调用invokeBeanFactoryPostProcessors()方法,就是在这个invokeBeanFactoryPostProcessors()方法中后续的调用过程中,会调用beanFactory对象的getBean()方法来获取Bean对象。本章,就一起分析从invokeBeanFactoryPostProcessors()方法中获取Bean对象的过程。
从IOC容器中获取Bean的过程的源码时序图如图4-1和4-2所示。
图4-1
图4-2
由图4-1和图4-2可以看出,从IOC容器中获取Bean的过程会涉及到BeanTest类、AnnotationConfigApplicationContext类、AbstractApplicationContext类、PostProcessorRegistrationDelegate类、AbstractBeanFactory类、DefaultSingletonBeanRegistry类和AbstractAutowireCapableBeanFactory类。具体的源码执行细节参见源码解析部分。
四、源码解析 源码时序图整清楚了,那就整源码解析呗!
从IOC容器中获取Bean的过程的源码执行流程,结合源码执行的时序图,会理解的更加深刻。
(1)运行案例程序启动类
案例程序启动类源码详见:spring-annotation-chapter-04工程下的io.binghe.spring.annotation.chapter04.BeanTest,运行BeanTest类的main()方法。
在BeanTest类的main()方法中调用了AnnotationConfigApplicationContext类的构造方法,并传入了ComponentScanConfig类的Class对象来创建IOC容器。接下来,会进入AnnotationConfigApplicationContext类的构造方法。
(2)解析AnnotationConfigApplicationContext类的AnnotationConfigApplicationContext(Class<?>... componentClasses)构造方法
源码详见:org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class<?>... componentClasses)。
复制 public AnnotationConfigApplicationContext( Class< ?> ... componentClasses) {
this( ) ;
register( componentClasses) ;
refresh( ) ;
}
可以看到,在上述构造方法中,调用了refresh()方法来刷新IOC容器。
(3)解析AbstractApplicationContext类的refresh()方法
源码详见:org.springframework.context.support.AbstractApplicationContext#refresh()。
复制 @Override
public void refresh( ) throws BeansException, IllegalStateException {
synchronized ( this.startupShutdownMonitor ) {
// ############省略其他代码##############
try {
// ############省略其他代码##############
invokeBeanFactoryPostProcessors( beanFactory) ;
// ############省略其他代码##############
} catch ( BeansException ex) {
// ############省略其他代码##############
} finally {
// ############省略其他代码##############
}
}
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. refresh()方法是Spring中一个非常重要的方法,很多重要的功能和特性都是通过refresh()方法进行注入的。可以看到,在refresh()方法中,调用了invokeBeanFactoryPostProcessors()方法。
(4)解析AbstractApplicationContext类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)方法
源码详见:org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)。
复制 protected void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors ( beanFactory, getBeanFactoryPostProcessors( ) ) ;
if ( ! NativeDetector.inNativeImage ( ) && beanFactory.getTempClassLoader ( ) == null && beanFactory.containsBean ( LOAD_TIME_WEAVER_BEAN_NAME) ) {
beanFactory.addBeanPostProcessor ( new LoadTimeWeaverAwareProcessor( beanFactory) ) ;
beanFactory.setTempClassLoader ( new ContextTypeMatchClassLoader( beanFactory.getBeanClassLoader ( ) ) ) ;
}
}
可以看到,在AbstractApplicationContext类的invokeBeanFactoryPostProcessors()方法中调用了PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors()方法。
(5)解析PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法
源码详见:org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)。
由于方法的源码比较长,这里,只关注当前最核心的逻辑,如下所示。
复制 public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List< BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// ############省略其他代码##############
List< BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<> ( ) ;
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[ ] postProcessorNames =
beanFactory.getBeanNamesForType ( BeanDefinitionRegistryPostProcessor.class , true , false ) ;
for ( String ppName : postProcessorNames) {
if ( beanFactory.isTypeMatch ( ppName, PriorityOrdered.class ) ) {
currentRegistryProcessors.add ( beanFactory.getBean ( ppName, BeanDefinitionRegistryPostProcessor.class ) ) ;
processedBeans.add ( ppName) ;
}
}
sortPostProcessors( currentRegistryProcessors, beanFactory) ;
registryProcessors.addAll ( currentRegistryProcessors) ;
invokeBeanDefinitionRegistryPostProcessors( currentRegistryProcessors, registry, beanFactory.getApplicationStartup ( ) ) ;
currentRegistryProcessors.clear ( ) ;
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType ( BeanDefinitionRegistryPostProcessor.class , true , false ) ;
for ( String ppName : postProcessorNames) {
if ( ! processedBeans.contains ( ppName) && beanFactory.isTypeMatch ( ppName, Ordered.class ) ) {
currentRegistryProcessors.add ( beanFactory.getBean ( ppName, BeanDefinitionRegistryPostProcessor.class ) ) ;
processedBeans.add ( ppName) ;
}
}
sortPostProcessors( currentRegistryProcessors, beanFactory) ;
registryProcessors.addAll ( currentRegistryProcessors) ;
invokeBeanDefinitionRegistryPostProcessors( currentRegistryProcessors, registry, beanFactory.getApplicationStartup ( ) ) ;
currentRegistryProcessors.clear ( ) ;
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true ;
while ( reiterate) {
reiterate = false ;
postProcessorNames = beanFactory.getBeanNamesForType ( BeanDefinitionRegistryPostProcessor.class , true , false ) ;
for ( String ppName : postProcessorNames) {
if ( ! processedBeans.contains ( ppName) ) {
currentRegistryProcessors.add ( beanFactory.getBean ( ppName, BeanDefinitionRegistryPostProcessor.class ) ) ;
processedBeans.add ( ppName) ;
reiterate = true ;
}
}
sortPostProcessors( currentRegistryProcessors, beanFactory) ;
registryProcessors.addAll ( currentRegistryProcessors) ;
invokeBeanDefinitionRegistryPostProcessors( currentRegistryProcessors, registry, beanFactory.getApplicationStartup ( ) ) ;
currentRegistryProcessors.clear ( ) ;
}
// ############省略其他代码##############
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 可以看到,在PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法中,有多处通过beanFactory对象的getBean()方法获取Bean对象的代码。
(6)解析AbstractBeanFactory类的getBean(String name, ClassrequiredType)方法
源码详见org.springframework.beans.factory.support.AbstractBeanFactory#getBean(String name, ClassrequiredType)。
复制 @Override
public < T> T getBean( String name, Class< T> requiredType) throws BeansException {
return doGetBean( name, requiredType, null , false ) ;
}
可以看到,getBean()方法调用了doGetBean()方法。
(7)解析AbstractBeanFactory类的doGetBean(String name, ClassrequiredType, Object[] args, boolean typeCheckOnly)方法
源码详见:org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean(String name, @Nullable ClassrequiredType, @Nullable Object[] args, boolean typeCheckOnly)。
复制 protected < T> T doGetBean(
String name, @Nullable Class< T> requiredType, @Nullable Object[ ] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName( name) ;
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton( beanName) ;
if ( sharedInstance != null && args == null ) {
if ( logger.isTraceEnabled ( ) ) {
if ( isSingletonCurrentlyInCreation( beanName) ) {
logger.trace ( "Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference" ) ;
}
else {
logger.trace ( "Returning cached instance of singleton bean '" + beanName + "'" ) ;
}
}
beanInstance = getObjectForBeanInstance( sharedInstance, name, beanName, null ) ;
}
else {
if ( isPrototypeCurrentlyInCreation( beanName) ) {
throw new BeanCurrentlyInCreationException( beanName) ;
}
BeanFactory parentBeanFactory = getParentBeanFactory( ) ;
if ( parentBeanFactory != null && ! containsBeanDefinition( beanName) ) {
// Not found -> check parent.
String nameToLookup = originalBeanName( name) ;
if ( parentBeanFactory instanceof AbstractBeanFactory abf) {
return abf.doGetBean ( nameToLookup, requiredType, args, typeCheckOnly) ;
}
else if ( args != null ) {
// Delegation to parent with explicit args.
return ( T) parentBeanFactory.getBean ( nameToLookup, args) ;
}
else if ( requiredType != null ) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean ( nameToLookup, requiredType) ;
}
else {
return ( T) parentBeanFactory.getBean ( nameToLookup) ;
}
}
if ( ! typeCheckOnly) {
markBeanAsCreated( beanName) ;
}
StartupStep beanCreation = this.applicationStartup .start ( "spring.beans.instantiate" )
.tag ( "beanName" , name) ;
try {
if ( requiredType != null ) {
beanCreation.tag ( "beanType" , requiredType:: toString) ;
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition( beanName) ;
checkMergedBeanDefinition( mbd, beanName, args) ;
// Guarantee initialization of beans that the current bean depends on .
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) ;
}
}
}
// Create bean instance.
if ( mbd.isSingleton ( ) ) {
sharedInstance = getSingleton( beanName, ( ) -> {
try {
return createBean( beanName, mbd, args) ;
}
catch ( BeansException ex) {
destroySingleton( beanName) ;
throw ex;
}
} ) ;
beanInstance = getObjectForBeanInstance( sharedInstance, name, beanName, mbd) ;
}
else if ( mbd.isPrototype ( ) ) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ' " + beanName + " '");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name ' " + scopeName + " '");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. doGetBean()方法的源码比较长,也是一个非常重要的方法,方法的大体流程如下所示。
先通过transformedBeanName()方法转换bean的名称,这里可能是FactoryBean的名称(&开头),需要转成不带&开头的名称,如果有别名,再获取别名。 从缓存中获取bean,这里的缓存分为一二三级缓存,也就是spring的三级缓存。 根据获取到的对象再去获取想要的Bean,因为这里获取到的对象可能是需要的Bean,也可能是FactoryBean(工厂Bean)。 如果缓存中没有,就去创建Bean对象。 查看有没有父类的BeanFactory,如果有,那么就使用父类去创建Bean对象。 获取要创建的Bean对象的@DependsOn注解上的名称,先去创建DependsOn的Bean,并且校验是否存在循环引用。 创建Bean,根据类型创建不同的Bean,比如singleton,prototype,request,session等。 如果需要转换类型,则进行类型转换。如果不需要转换类型,就不转换类型。 本章后续的源码解析部分,都是以doGetBean()方法作为基础进行解析的。
(8)解析DefaultSingletonBeanRegistry类的getSingleton(String beanName)方法
源码详见:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(String beanName)
复制 @Override
@Nullable
public Object getSingleton( String beanName) {
return getSingleton( beanName, true ) ;
}
可以看到,在getSingleton()方法中调用了另一个getSingleton()方法。
(9)解析DefaultSingletonBeanRegistry类的getSingleton(String beanName, boolean allowEarlyReference)方法
源码详见:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference)。
复制 @Nullable
protected Object getSingleton( String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects .get ( beanName) ;
if ( singletonObject == null && isSingletonCurrentlyInCreation( beanName) ) {
singletonObject = this.earlySingletonObjects .get ( beanName) ;
if ( singletonObject == null && allowEarlyReference) {
synchronized ( this.singletonObjects ) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects .get ( beanName) ;
if ( singletonObject == null ) {
singletonObject = this.earlySingletonObjects .get ( beanName) ;
if ( singletonObject == null ) {
ObjectFactory< ?> singletonFactory = this.singletonFactories .get ( beanName) ;
if ( singletonFactory != null ) {
singletonObject = singletonFactory.getObject ( ) ;
this.earlySingletonObjects .put ( beanName, singletonObject) ;
this.singletonFactories .remove ( beanName) ;
}
}
}
}
}
}
return singletonObject;
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 在Spring中,这个getSingleton(String beanName, boolean allowEarlyReference)方法是个非常重要的方法,这个方法中使用了Spring的三级缓存,在后续的文章中,还会对这个方法进行深度解析。这里,先给大家介绍下Spring的三级缓存。
singletonObjects:一级缓存,实例化的Bean都会存储在这个Map集合中。 earlySingletonObjects:二级缓存,存放未完成的bean的缓存,如果有代理的话,存放的是代理对象。 singletonFactories:三级缓存,存放的是一个ObjectFactory,数据通过getObject方法获得。 (10)解析AbstractBeanFactory类的getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd)方法
源码详见:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd)。
复制 protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// name是否是以& 开头
if ( BeanFactoryUtils.isFactoryDereference ( name) ) {
if ( beanInstance instanceof NullBean) {
return beanInstance;
}
if ( ! ( beanInstance instanceof FactoryBean) ) {
throw new BeanIsNotAFactoryException( beanName, beanInstance.getClass ( ) ) ;
}
if ( mbd != null ) {
mbd.isFactoryBean = true ;
}
return beanInstance;
}
// 如果bean不是FactoryBean,直接返回beanInstance
if ( ! ( beanInstance instanceof FactoryBean< ?> factoryBean) ) {
return beanInstance;
}
Object object = null ;
if ( mbd != null ) {
mbd.isFactoryBean = true ;
}
else {
// 从缓存中获取对象
object = getCachedObjectForFactoryBean( beanName) ;
}
if ( object == null ) {
if ( mbd == null && containsBeanDefinition( beanName) ) {
mbd = getMergedLocalBeanDefinition( beanName) ;
}
boolean synthetic = ( mbd != null && mbd.isSynthetic ( ) ) ;
// 通过FactoryBean获取需要的beanInstance
object = getObjectFromFactoryBean( factoryBean, beanName, ! synthetic) ;
}
return object;
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 整个getObjectForBeanInstance()方法的源码还算是比较简单,大家多看几遍就能理解。这里,给大家说明下大体的流程。
首先判断name是不是FactoryBean的name,也就是&开头的name,如果beanInstance不是FactoryBean则抛异常。 如果name是FactoryBeanName,那么需要获取的就是FactoryBean,直接返回对象。 如果都没有返回,那么已经可以确定此时已经可以确定beanInstance是FactoryBean了,因为如果不是FactoryBean在(beanInstance instanceof FactoryBean)就已经返回了。 通过FactoryBean的getObject方法获取需要的Bean实例。 (11)解析DefaultSingletonBeanRegistry类的getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法。
源码详见:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)。
复制 public Object getSingleton( String beanName, ObjectFactory< ?> singletonFactory) {
Assert.notNull ( beanName, "Bean name must not be null" ) ;
synchronized ( this.singletonObjects ) {
Object singletonObject = this.singletonObjects .get ( beanName) ;
if ( singletonObject == null ) {
if ( this.singletonsCurrentlyInDestruction ) {
// #########省略异常代码################
}
if ( logger.isDebugEnabled ( ) ) {
logger.debug ( "Creating shared instance of singleton bean '" + beanName + "'" ) ;
}
beforeSingletonCreation( beanName) ;
boolean newSingleton = false ;
boolean recordSuppressedExceptions = ( this.suppressedExceptions == null ) ;
if ( recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<> ( ) ;
}
try {
// 获取创建的bean
singletonObject = singletonFactory.getObject ( ) ;
newSingleton = true ;
}
catch ( IllegalStateException ex) {
singletonObject = this.singletonObjects .get ( beanName) ;
if ( singletonObject == null ) {
throw ex;
}
}
catch ( BeanCreationException ex) {
if ( recordSuppressedExceptions) {
for ( Exception suppressedException : this.suppressedExceptions ) {
ex.addRelatedCause ( suppressedException) ;
}
}
throw ex;
}
finally {
if ( recordSuppressedExceptions) {
this.suppressedExceptions = null ;
}
afterSingletonCreation( beanName) ;
}
if ( newSingleton) {
// 将创建的Bean对象加到一级缓存中
addSingleton( beanName, singletonObject) ;
}
}
return singletonObject;
}
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 在上述getSingleton()方法中,传入了一个beanName和一个singletonFactory来创建单实例Bean对象,ObjectFactory类中封装了创建Bean的具体逻辑。在上述getSingleton()方法中,创建Bean对象之前调用了 beforeSingletonCreation()方法,在创建对象之后调用了afterSingletonCreation()方法。两个方法的源码如下所示。
复制 protected void beforeSingletonCreation( String beanName) {
if ( ! this.inCreationCheckExclusions .contains ( beanName) && ! this.singletonsCurrentlyInCreation .add ( beanName) ) {
throw new BeanCurrentlyInCreationException( beanName) ;
}
}
protected void afterSingletonCreation( String beanName) {
if ( ! this.inCreationCheckExclusions .contains ( beanName) && ! this.singletonsCurrentlyInCreation .remove ( beanName) ) {
throw new IllegalStateException( "Singleton '" + beanName + "' isn't currently in creation" ) ;
}
}
可以看到,beforeSingletonCreation()方法和afterSingletonCreation()方法的执行逻辑比较简单,这里不再赘述。
(12)回到AbstractBeanFactory类的doGetBean(String name, ClassrequiredType, Object[] args, boolean typeCheckOnly)方法,这里重点看如下代码片段。
复制 if ( mbd.isSingleton ( ) ) {
sharedInstance = getSingleton( beanName, ( ) -> {
try {
return createBean( beanName, mbd, args) ;
}
catch ( BeansException ex) {
destroySingleton( beanName) ;
throw ex;
}
} ) ;
beanInstance = getObjectForBeanInstance( sharedInstance, name, beanName, mbd) ;
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 可以看到,调用了createBean()方法来创建Bean对象。
(13)解析AbstractAutowireCapableBeanFactory类的createBean(String beanName, RootBeanDefinition mbd, Object[] args)方法
源码详见:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
复制 @Override
protected Object createBean( String beanName, RootBeanDefinition mbd, @Nullable Object[ ] args)
throws BeanCreationException {
// ##############省略其他代码############
try {
Object beanInstance = doCreateBean( beanName, mbdToUse, args) ;
if ( logger.isTraceEnabled ( ) ) {
logger.trace ( "Finished creating instance of bean '" + beanName + "'" ) ;
}
return beanInstance;
}
// ##############省略其他代码############
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 在createBean()方法中,只是做了一些准备工作,并没有真正的创建Bean对象,真正创建Bean对象是在doCreateBean()方法中完成的。
(14)解析AbstractAutowireCapableBeanFactory类的doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args)方法
源码详见:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)。
复制 protected Object doCreateBean( String beanName, RootBeanDefinition mbd, @Nullable Object[ ] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null ;
if ( mbd.isSingleton ( ) ) {
instanceWrapper = this.factoryBeanInstanceCache .remove ( beanName) ;
}
if ( instanceWrapper == null ) {
instanceWrapper = createBeanInstance( beanName, mbd, args) ;
}
Object bean = instanceWrapper.getWrappedInstance ( ) ;
Class< ?> beanType = instanceWrapper.getWrappedClass ( ) ;
if ( beanType != NullBean.class ) {
mbd.resolvedTargetType = beanType;
}
synchronized ( mbd.postProcessingLock ) {
if ( ! mbd.postProcessed ) {
try {
applyMergedBeanDefinitionPostProcessors( mbd, beanType, beanName) ;
}
catch ( Throwable ex) {
throw new BeanCreationException( mbd.getResourceDescription ( ) , beanName,
"Post-processing of merged bean definition failed" , ex) ;
}
mbd.markAsPostProcessed ( ) ;
}
}
boolean earlySingletonExposure = ( mbd.isSingleton ( ) && this.allowCircularReferences &&
isSingletonCurrentlyInCreation( beanName) ) ;
if ( earlySingletonExposure) {
if ( logger.isTraceEnabled ( ) ) {
logger.trace ( "Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references" ) ;
}
addSingletonFactory( beanName, ( ) -> getEarlyBeanReference( beanName, mbd, bean) ) ;
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean( beanName, mbd, instanceWrapper) ;
exposedObject = initializeBean( beanName, exposedObject, mbd) ;
}
catch ( Throwable ex) {
if ( ex instanceof BeanCreationException bce && beanName.equals ( bce.getBeanName ( ) ) ) {
throw bce;
}
else {
throw new BeanCreationException( mbd.getResourceDescription ( ) , beanName, ex.getMessage ( ) , ex) ;
}
}
if ( earlySingletonExposure) {
Object earlySingletonReference = getSingleton( beanName, false ) ;
if ( earlySingletonReference != null ) {
if ( exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if ( ! this.allowRawInjectionDespiteWrapping && hasDependentBean( beanName) ) {
String[ ] dependentBeans = getDependentBeans( beanName) ;
Set < String> actualDependentBeans = new LinkedHashSet<> ( dependentBeans.length ) ;
for ( String dependentBean : dependentBeans) {
if ( ! removeSingletonIfCreatedForTypeCheckOnly( dependentBean) ) {
actualDependentBeans.add ( dependentBean) ;
}
}
if ( ! actualDependentBeans.isEmpty ( ) ) {
// ###############省略异常代码#################
}
}
}
}
try {
registerDisposableBeanIfNecessary( beanName, bean, mbd) ;
}
catch ( BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription ( ) , beanName, "Invalid destruction signature" , ex) ;
}
return exposedObject;
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. doCreateBean()方法的逻辑看上去还是挺复杂的。大体的流程如下所示。
调用createBeanInstance()方法创建bean。 调用属于applyMergedBeanDefinitionPostProcessors()方法。对Bean进行一些处理。 将bean加入到三级缓存中。 填充Bean需要注入的其他Bean对象。 调用初始化方法,先去调用@PostConstruct注解方法,然后调用InitializingBean的afterPropertiesSet,以及自定义的init-method方法。在Bean调用初始化方法之后,再去调用后置处理器接口检测是否需要生成Aop代理。 接着进行校验。这里稍微比较复杂一点。如果从二级缓存能取到,那就说明之前已经从三级缓存获取过。可能是因为循环依赖,也可能是因为别的地方调用了getBean方法。从三级缓存获取时有个getEarlyBeanReference()的方法,就是查看是否要生成代理的bean。如果已经生成代理的Bean,那么在调用初始化方法时,就不会在生成代理Bean了。这样满足exposedObject ==bean,直接只用代理返回。 如果exposedObject和bean不相等:这里的情况就是:如果是spring的@Async注解,在从二级缓存生成代理之后,再去调用初始化方法时,一样会生成代理。所以此时exposedObject不等于bean,再往下发现有循环调用,并且Bean还在创建时,就会抛出异常。 至此,从IOC容器中获取Bean的大体流程分析完毕。
五、总结 从IOC容器中获取Bean的大体流程分析完了,总结下吧?
本章,主要对从IOC容器中获取Bean的过程进行了简单的介绍。首先,通过一个测试案例来引出调试源码的过程,随后,结合源码执行的时序图详细分析了从IOC容器中获取Bean的过程源码。
六、思考 既然学完了,就开始思考几个问题吧?
Spring为何会有循环依赖的问题? Spring如何解决循环依赖问题? Spring为何使用三级缓存解决循环依赖问题?使用二级缓存不行吗?为什么? Spring中为何把创建Bean对象设计的如此复杂?你觉得是出于哪方面的考虑呢? 从Spring的设计中,你学到了什么?