一丰滑、bean的實(shí)例化過(guò)程源碼分析
上一章節(jié)講了bean定義的加載過(guò)程混狠,現(xiàn)在我們來(lái)講一下bean的實(shí)例化過(guò)程糠悼,bean的實(shí)例化形真,主要是finishBeanFactoryInitialization(beanFactory);這個(gè)方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//bean工廠創(chuàng)建轉(zhuǎn)化器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//實(shí)例化AOP相關(guān)的組件
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//調(diào)用工廠實(shí)例化方法抡砂,這個(gè)方法我們后面來(lái)分析
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
//凍結(jié)所有bean定義,在實(shí)例化時(shí)窒篱,不允許再修改bean定義
beanFactory.freezeConfiguration();
//實(shí)例化所有bean
beanFactory.preInstantiateSingletons();
}
//實(shí)例化所有bean
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//獲取到容器中所有bean定義
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//循環(huán)去實(shí)例化
for (String beanName : beanNames) {
//把各種不同類型的bean定義轉(zhuǎn)換成RootBeanDefinition類型
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//只有不是抽象類焕刮,必須是單例類,并且不是懶加載才會(huì)去實(shí)例化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判斷是不是工廠類
if (isFactoryBean(beanName)) {
//工廠類會(huì)先生存實(shí)際的bean墙杯,用 &+bean名稱
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//實(shí)際去實(shí)例化bean
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//調(diào)用實(shí)例化bean
getBean(beanName);
}
}
}
//遍歷所有的bean配并,如果實(shí)現(xiàn)了SmartInitializingSingleton接口,調(diào)用afterSingletonsInstantiated方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
public Object getBean(String name) throws BeansException {
//真實(shí)去實(shí)例化bean
return doGetBean(name, null, null, false);
}
//這個(gè)方法就是最重要的實(shí)例化過(guò)程高镐,最主要是關(guān)注spring是怎么解決循環(huán)依賴的
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object bean;
//先從一級(jí)緩存中去獲取bean溉旋,可以看下getSingleton方法
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 + "'");
}
}
//如果是普通單例bean則會(huì)直接返回,如果是工廠bean嫉髓。則會(huì)調(diào)用getObject獲取真正的bean實(shí)例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//Spring只解決單例bean的循環(huán)依賴观腊,如果非單例,循環(huán)依賴則會(huì)直接報(bào)錯(cuò)
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
//獲取到父工廠算行,如果當(dāng)前工廠中沒(méi)有當(dāng)前bean恕沫,則委托給父工廠實(shí)例化
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//如果不僅僅做類型檢查,而是創(chuàng)建bean纱意,則標(biāo)記這個(gè)bean
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//把不同類型的bean定義轉(zhuǎn)換成RootBeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//如果是抽象類,則會(huì)報(bào)錯(cuò)
checkMergedBeanDefinition(mbd, beanName, args);
//處理dependsOn依賴
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//如果依賴的bean是正在創(chuàng)建的bean鲸阔,就是循環(huán)依賴問(wèn)題偷霉,這個(gè)直接拋異常迄委,這種是@Bean依賴,不給解決循環(huán)依賴
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);
}
}
}
//如果是單例bean放進(jìn)三級(jí)緩存类少,并且獲取依賴注入的bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//這段邏輯可以看下面createBean的詳解
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//創(chuàng)建bean的邏輯報(bào)異常叙身,則銷毀當(dāng)前bean相關(guān)的所有信息
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = 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);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//第一步先從緩存中獲取bean
Object singletonObject = this.singletonObjects.get(beanName);
//如果沒(méi)有獲取到bean,并且這個(gè)bean正在實(shí)例化過(guò)程中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//從二級(jí)緩存中獲取bean
singletonObject = this.earlySingletonObjects.get(beanName);
//如果未獲取到
if (singletonObject == null && allowEarlyReference) {
//先對(duì)一級(jí)緩存加鎖硫狞,保證獲取到的是一個(gè)實(shí)例化完成的bean
synchronized (this.singletonObjects) {
//因?yàn)楂@取到鎖信轿,可能這個(gè)bean已經(jīng)放入到一級(jí)緩存,如果不去獲取一次残吩,可能出現(xiàn)多個(gè)bean
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
//然后再去從二級(jí)緩存中獲取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
//然后從三級(jí)緩存中獲取生成bean的方法财忽,這是解決循環(huán)依賴的關(guān)鍵,生成代理類泣侮,也是這個(gè)方法調(diào)用后才生成的
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//調(diào)用這個(gè)鉤子方法即彪,我們?cè)谏弦粋€(gè)方法doGetBean中可以找到這個(gè)鉤子方法
singletonObject = singletonFactory.getObject();
//然后把這個(gè)類放到二級(jí)緩存中
this.earlySingletonObjects.put(beanName, singletonObject);
//再?gòu)娜?jí)緩存中移除這個(gè)bean
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
}
//獲取單例bean
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//加鎖,如果同時(shí)有多線程在獲取bean活尊,保證不會(huì)獲取到不完成的bean
synchronized (this.singletonObjects) {
//獲取到鎖后先從一級(jí)緩存中獲取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//標(biāo)記當(dāng)前bean正在被創(chuàng)建隶校,用于判斷是否是循環(huán)依賴,就是加入到set集合中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//調(diào)用外面?zhèn)魅脒M(jìn)來(lái)的createBean鉤子方法
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) {
addSingleton(beanName, singletonObject);
}
}
//返回實(shí)例化后的bean
return singletonObject;
}
}
//實(shí)例化bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//調(diào)用第一個(gè)bean的后置處理器蛹锰,生成代理對(duì)象深胳,我們一般的AOP是不會(huì)在這里生成代理的,因?yàn)檫€沒(méi)實(shí)例化出對(duì)象
//這里這里是AOP和事務(wù)的關(guān)鍵铜犬,會(huì)生成切面信息進(jìn)行緩存
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//真正去創(chuàng)建bean舞终,進(jìn)行實(shí)例化
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
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);
}
//獲取早期對(duì)象
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.postProcessed = true;
}
}
/**
* 這一段就是循環(huán)依賴最關(guān)鍵的點(diǎn),會(huì)先放一個(gè)早期對(duì)象到鉤子方法(getEarlyBeanReference)中
* 這個(gè)鉤子方法如果這個(gè)對(duì)象不用創(chuàng)建動(dòng)態(tài)代理翎苫,則會(huì)直接返回當(dāng)前對(duì)象
* 把這個(gè)鉤子方法放入三級(jí)緩存权埠,等真正來(lái)獲取bean時(shí),執(zhí)行
* 過(guò)了這段邏輯煎谍,才開始去注入各種屬性攘蔽,如果有需要循環(huán)獲取的屬性,則會(huì)從三級(jí)緩存中獲取
**/
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));
}
Object exposedObject = bean;
try {
//去注入屬性呐粘,比如有依賴的屬性满俗,則是從這里去注入,會(huì)循環(huán)調(diào)用getBean
populateBean(beanName, mbd, instanceWrapper);
/**
* 到這一步作岖,對(duì)象已經(jīng)實(shí)例化完成
* 如果有經(jīng)過(guò)循環(huán)依賴的話唆垃,需要進(jìn)行動(dòng)態(tài)代理的類,已經(jīng)生成了動(dòng)態(tài)代理
* 但是痘儡,未經(jīng)過(guò)循環(huán)依賴的類辕万,需要我們實(shí)例化完成后,進(jìn)行動(dòng)態(tài)代理
* 動(dòng)態(tài)代理時(shí),還需判斷是否是接口渐尿,需要用JDK的動(dòng)態(tài)代理醉途,還是CGLIB的動(dòng)態(tài)代理
**/
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
//如果是正常bean,一般只會(huì)從一級(jí)或者二級(jí)緩存中獲取砖茸,不會(huì)把bean存入三級(jí)緩存
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()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
//注冊(cè)銷毀的bean的銷毀接口
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
Spring IOC容器bean的實(shí)例化隘擎,到這基本就完成了,這次所有源代碼的分析把重要的地方凉夯,大致流程都講了一遍货葬,但是有很多細(xì)節(jié)沒(méi)有講到,比如說(shuō)怎么創(chuàng)建動(dòng)態(tài)代理劲够,怎么具體怎么實(shí)例化震桶,這些代碼根據(jù)我的注釋找到相應(yīng)的地方,可以去自己看看源碼再沧,我基本上都標(biāo)注了每一步的步驟尼夺,只是如果要深挖的話,層級(jí)太深炒瘸,繞也會(huì)繞暈淤堵,最好是自己腦子里有個(gè)框架,然后再根據(jù)框架去找細(xì)節(jié)顷扩,這樣就會(huì)事半功倍拐邪。
二、最后總結(jié)
這次Spring只分析了源代碼隘截,這次就分析到這里扎阶,其實(shí)我們分析源代碼不僅僅只是知道它內(nèi)部邏輯是怎么運(yùn)行的,關(guān)鍵是需要學(xué)習(xí)這個(gè)框架的思想婶芭,以及各種設(shè)計(jì)模式的運(yùn)用东臀,這樣才算學(xué)到了東西;其實(shí)Spring的代碼犀农,你過(guò)了一段時(shí)間惰赋,基本上就只會(huì)記得大概,主要是確實(shí)層級(jí)太深呵哨,所以我們需要了解到精髓赁濒,例如里面生成bean用到的工廠模式,去解析@ComponentScan孟害,里面的這個(gè)type用到的策略模式拒炎,還有AOP切面調(diào)用advisor使用的責(zé)任鏈模式,等等挨务,都是我們學(xué)習(xí)的點(diǎn)击你;