新聞中心
一、學(xué)習(xí)指引?
你了解過(guò)從Spring IOC容器中獲取Bean的過(guò)程嗎?

成都創(chuàng)新互聯(lián)公司專(zhuān)注于企業(yè)全網(wǎng)整合營(yíng)銷(xiāo)推廣、網(wǎng)站重做改版、平邑網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性?xún)r(jià)比高,為平邑等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
學(xué)習(xí)過(guò)Spring的小伙伴都知道:如果是單實(shí)例Bean,則IOC容器啟動(dòng)時(shí),就會(huì)創(chuàng)建Bean對(duì)象,IOC容器關(guān)閉時(shí),銷(xiāo)毀Bean對(duì)象。如果是多實(shí)例Bean,IOC容器在啟動(dòng)時(shí),不會(huì)創(chuàng)建Bean對(duì)象,在每次從IOC容器中獲取Bean對(duì)象時(shí),都會(huì)創(chuàng)建新的Bean對(duì)象返回,IOC容器關(guān)閉時(shí),也不會(huì)銷(xiāo)毀對(duì)象。也就是說(shuō),如果是多實(shí)例Bean,IOC容器不會(huì)管理Bean對(duì)象。
那從IOC容器中獲取Bean的具體過(guò)程是怎樣的呢?想深度學(xué)習(xí)Spring源碼的小伙伴繼續(xù)往下看。
二、測(cè)試案例?
整個(gè)調(diào)試Spring6.0源碼的案例玩玩兒?jiǎn)h?
本章的案例比較簡(jiǎn)單,只是實(shí)現(xiàn)一個(gè)用于調(diào)試源碼的小案例,具體的實(shí)現(xiàn)步驟如下所示。
(1)創(chuàng)建配置類(lèi)BeanConfig
BeanConfig類(lèi)的源碼詳見(jiàn):spring-annotation-chapter-04工程下的io.binghe.spring.annotation.chapter04.config.BeanConfig。
@Configuration
@ComponentScan(basePackages = "io.binghe.spring.annotation.chapter04")
public class BeanConfig {
}
可以看到,在BeanConfig類(lèi)上標(biāo)注了@Configuration注解,說(shuō)明BeanConfig類(lèi)是Spring的配置類(lèi),使用@ComponentScan注解標(biāo)注了掃描的包是io.binghe.spring.annotation.chapter04。
(2)創(chuàng)建測(cè)試類(lèi)BeanTest
BeanTest類(lèi)的源碼詳見(jiàn):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類(lèi)中只是簡(jiǎn)單的使用AnnotationConfigApplicationContext類(lèi)創(chuàng)建IOC容器,并關(guān)閉IOC容器。
好了,測(cè)試案例準(zhǔn)備好了,接下來(lái),就一步步分析從IOC容器中獲取Bean的過(guò)程。
三、源碼時(shí)序圖?
結(jié)合時(shí)序圖理解源碼會(huì)事半功倍,你覺(jué)得呢?
其實(shí),經(jīng)過(guò)前面章節(jié)的學(xué)習(xí),細(xì)心的小伙伴在調(diào)試Spring源碼的過(guò)程中會(huì)發(fā)現(xiàn),在Spring的AbstractApplicationContext類(lèi)中的refresh()方法中,會(huì)調(diào)用invokeBeanFactoryPostProcessors()方法,就是在這個(gè)invokeBeanFactoryPostProcessors()方法中后續(xù)的調(diào)用過(guò)程中,會(huì)調(diào)用beanFactory對(duì)象的getBean()方法來(lái)獲取Bean對(duì)象。本章,就一起分析從invokeBeanFactoryPostProcessors()方法中獲取Bean對(duì)象的過(guò)程。
從IOC容器中獲取Bean的過(guò)程的源碼時(shí)序圖如圖4-1和4-2所示。
圖4-1
圖4-2
由圖4-1和圖4-2可以看出,從IOC容器中獲取Bean的過(guò)程會(huì)涉及到BeanTest類(lèi)、AnnotationConfigApplicationContext類(lèi)、AbstractApplicationContext類(lèi)、PostProcessorRegistrationDelegate類(lèi)、AbstractBeanFactory類(lèi)、DefaultSingletonBeanRegistry類(lèi)和AbstractAutowireCapableBeanFactory類(lèi)。具體的源碼執(zhí)行細(xì)節(jié)參見(jiàn)源碼解析部分。
四、源碼解析?
源碼時(shí)序圖整清楚了,那就整源碼解析唄!
從IOC容器中獲取Bean的過(guò)程的源碼執(zhí)行流程,結(jié)合源碼執(zhí)行的時(shí)序圖,會(huì)理解的更加深刻。
(1)運(yùn)行案例程序啟動(dòng)類(lèi)
案例程序啟動(dòng)類(lèi)源碼詳見(jiàn):spring-annotation-chapter-04工程下的io.binghe.spring.annotation.chapter04.BeanTest,運(yùn)行BeanTest類(lèi)的main()方法。
在BeanTest類(lèi)的main()方法中調(diào)用了AnnotationConfigApplicationContext類(lèi)的構(gòu)造方法,并傳入了ComponentScanConfig類(lèi)的Class對(duì)象來(lái)創(chuàng)建IOC容器。接下來(lái),會(huì)進(jìn)入AnnotationConfigApplicationContext類(lèi)的構(gòu)造方法。
(2)解析AnnotationConfigApplicationContext類(lèi)的AnnotationConfigApplicationContext(Class>... componentClasses)構(gòu)造方法
源碼詳見(jiàn):org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(Class>... componentClasses)。
public AnnotationConfigApplicationContext(Class>... componentClasses) {
this();
register(componentClasses);
refresh();
}可以看到,在上述構(gòu)造方法中,調(diào)用了refresh()方法來(lái)刷新IOC容器。
(3)解析AbstractApplicationContext類(lèi)的refresh()方法
源碼詳見(jiàn):org.springframework.context.support.AbstractApplicationContext#refresh()。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//############省略其他代碼##############
try {
//############省略其他代碼##############
invokeBeanFactoryPostProcessors(beanFactory);
//############省略其他代碼##############
}catch (BeansException ex) {
//############省略其他代碼##############
}finally {
//############省略其他代碼##############
}
}
}
refresh()方法是Spring中一個(gè)非常重要的方法,很多重要的功能和特性都是通過(guò)refresh()方法進(jìn)行注入的??梢钥吹剑趓efresh()方法中,調(diào)用了invokeBeanFactoryPostProcessors()方法。
(4)解析AbstractApplicationContext類(lèi)的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)方法
源碼詳見(jiàn):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類(lèi)的invokeBeanFactoryPostProcessors()方法中調(diào)用了PostProcessorRegistrationDelegate類(lèi)的invokeBeanFactoryPostProcessors()方法。
(5)解析PostProcessorRegistrationDelegate類(lèi)的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法
源碼詳見(jiàn):org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)。
由于方法的源碼比較長(zhǎng),這里,只關(guān)注當(dāng)前最核心的邏輯,如下所示。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors) {
//############省略其他代碼##############
ListcurrentRegistryProcessors = 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();
}
//############省略其他代碼##############
}
可以看到,在PostProcessorRegistrationDelegate類(lèi)的invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors)方法中,有多處通過(guò)beanFactory對(duì)象的getBean()方法獲取Bean對(duì)象的代碼。
(6)解析AbstractBeanFactory類(lèi)的getBean(String name, ClassrequiredType)方法
源碼詳見(jiàn)org.springframework.beans.factory.support.AbstractBeanFactory#getBean(String name, ClassrequiredType)。
@Override
publicT getBean(String name, Class requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
可以看到,getBean()方法調(diào)用了doGetBean()方法。
(7)解析AbstractBeanFactory類(lèi)的doGetBean(String name, ClassrequiredType, Object[] args, boolean typeCheckOnly)方法
源碼詳見(jiàn):org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean(String name, @Nullable ClassrequiredType, @Nullable Object[] args, boolean typeCheckOnly)。
protectedT doGetBean(
String name, @Nullable ClassrequiredType, @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);
}
doGetBean()方法的源碼比較長(zhǎng),也是一個(gè)非常重要的方法,方法的大體流程如下所示。
- 先通過(guò)transformedBeanName()方法轉(zhuǎn)換bean的名稱(chēng),這里可能是FactoryBean的名稱(chēng)(&開(kāi)頭),需要轉(zhuǎn)成不帶&開(kāi)頭的名稱(chēng),如果有別名,再獲取別名。
- 從緩存中獲取bean,這里的緩存分為一二三級(jí)緩存,也就是spring的三級(jí)緩存。
- 根據(jù)獲取到的對(duì)象再去獲取想要的Bean,因?yàn)檫@里獲取到的對(duì)象可能是需要的Bean,也可能是FactoryBean(工廠Bean)。
- 如果緩存中沒(méi)有,就去創(chuàng)建Bean對(duì)象。
- 查看有沒(méi)有父類(lèi)的BeanFactory,如果有,那么就使用父類(lèi)去創(chuàng)建Bean對(duì)象。
- 獲取要?jiǎng)?chuàng)建的Bean對(duì)象的@DependsOn注解上的名稱(chēng),先去創(chuàng)建DependsOn的Bean,并且校驗(yàn)是否存在循環(huán)引用。
- 創(chuàng)建Bean,根據(jù)類(lèi)型創(chuàng)建不同的Bean,比如singleton,prototype,request,session等。
- 如果需要轉(zhuǎn)換類(lèi)型,則進(jìn)行類(lèi)型轉(zhuǎn)換。如果不需要轉(zhuǎn)換類(lèi)型,就不轉(zhuǎn)換類(lèi)型。
本章后續(xù)的源碼解析部分,都是以doGetBean()方法作為基礎(chǔ)進(jìn)行解析的。
(8)解析DefaultSingletonBeanRegistry類(lèi)的getSingleton(String beanName)方法
源碼詳見(jiàn):org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(String beanName)
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
可以看到,在getSingleton()方法中調(diào)用了另一個(gè)getSingleton()方法。
(9)解析DefaultSingletonBeanRegistry類(lèi)的getSingleton(String beanName, boolean allowEarlyReference)方法
源碼詳見(jiàn):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;
}
在Spring中,這個(gè)getSingleton(String beanName, boolean allowEarlyReference)方法是個(gè)非常重要的方法,這個(gè)方法中使用了Spring的三級(jí)緩存,在后續(xù)的文章中,還會(huì)對(duì)這個(gè)方法進(jìn)行深度解析。這里,先給大家介紹下Spring的三級(jí)緩存。
- singletonObjects:一級(jí)緩存,實(shí)例化的Bean都會(huì)存儲(chǔ)在這個(gè)Map集合中。
- earlySingletonObjects:二級(jí)緩存,存放未完成的bean的緩存,如果有代理的話(huà),存放的是代理對(duì)象。
- singletonFactories:三級(jí)緩存,存放的是一個(gè)ObjectFactory,數(shù)據(jù)通過(guò)getObject方法獲得。
(10)解析AbstractBeanFactory類(lèi)的getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd)方法
源碼詳見(jiàn):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是否是以&開(kāi)頭
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 {
//從緩存中獲取對(duì)象
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//通過(guò)FactoryBean獲取需要的beanInstance
object = getObjectFromFactoryBean(factoryBean, beanName, !synthetic);
}
return object;
}
整個(gè)getObjectForBeanInstance()方法的源碼還算是比較簡(jiǎn)單,大家多看幾遍就能理解。這里,給大家說(shuō)明下大體的流程。
- 首先判斷name是不是FactoryBean的name,也就是&開(kāi)頭的name,如果beanInstance不是FactoryBean則拋異常。
- 如果name是FactoryBeanName,那么需要獲取的就是FactoryBean,直接返回對(duì)象。
- 如果都沒(méi)有返回,那么已經(jīng)可以確定此時(shí)已經(jīng)可以確定beanInstance是FactoryBean了,因?yàn)槿绻皇荈actoryBean在(beanInstance instanceof FactoryBean)就已經(jīng)返回了。
- 通過(guò)FactoryBean的getObject方法獲取需要的Bean實(shí)例。
(11)解析DefaultSingletonBeanRegistry類(lèi)的getSingleton(String beanName, ObjectFactory> singletonFactory)方法。
源碼詳見(jiàn):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 {
//獲取創(chuàng)建的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) {
//將創(chuàng)建的Bean對(duì)象加到一級(jí)緩存中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}在上述getSingleton()方法中,傳入了一個(gè)beanName和一個(gè)singletonFactory來(lái)創(chuàng)建單實(shí)例Bean對(duì)象,ObjectFactory類(lèi)中封裝了創(chuàng)建Bean的具體邏輯。在上述getSingleton()方法中,創(chuàng)建Bean對(duì)象之前調(diào)用了 beforeSingletonCreation()方法,在創(chuàng)建對(duì)象之后調(diào)用了afterSingletonCreation()方法。兩個(gè)方法的源碼如下所示。
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()方法的執(zhí)行邏輯比較簡(jiǎn)單,這里不再贅述。
(12)回到AbstractBeanFactory類(lèi)的doGetBean(String name, ClassrequiredType, Object[] args, boolean typeCheckOnly)方法,這里重點(diǎn)看如下代碼片段。
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);
}可以看到,調(diào)用了createBean()方法來(lái)創(chuàng)建Bean對(duì)象。
(13)解析AbstractAutowireCapableBeanFactory類(lèi)的createBean(String beanName, RootBeanDefinition mbd, Object[] args)方法
源碼詳見(jiàn):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 creati
分享標(biāo)題:深度解析從IOC容器中獲取Bean的過(guò)程
網(wǎng)站鏈接:http://fisionsoft.com.cn/article/coepggd.html


咨詢(xún)
建站咨詢(xún)
