第四節(jié)課:spring bean的實例化過程
在我們容器中 TLog tLog = tcx.getBean(TulingLog.class); 容器中的過程是什么?
i1:>org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
i2>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
i2.1>:org.springframework.beans.factory.support.AbstractBeanFactory#transformedBeanName 轉換
beanName
i2.2>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton 去緩存
中獲取bean
i2.3>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance 對
緩存中的獲取的bean進行后續(xù)處理
i2.4>:org.springframework.beans.factory.support.AbstractBeanFactory#isPrototypeCurrentlyInCreation
判斷原型bean的依賴注入
i2.5>:org.springframework.beans.factory.support.AbstractBeanFactory#getParentBeanFactory 檢查父
容器加載bean
i2.6>:org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition 將
bean定義轉為RootBeanDifination
i2.7>:檢查bean的依賴(bean加載順序的依賴)
i2.8>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton根據(jù)
scope 的添加來創(chuàng)建bean
i3>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean創(chuàng)建
bean的方法
i4>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 真
正的創(chuàng)建bean的邏輯
i4.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
調用構造函數(shù)創(chuàng)建對象
i4.2>:判斷是否需要提早暴露對象(mbd.isSingleton() && this.allowCircularReferences && i
sSingletonCurrentlyInCreation(beanName));
i4.3>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
暴露對象解決循環(huán)依賴
i4.4>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
給創(chuàng)建的bean進行賦值
i4.5>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean對
bean進行初始化
i4.5.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
調用XXAware接口
i4.5.2>applyBeanPostProcessorsBeforeInitialization 調用bean的后置處理器進行對處理
i4.5.2>applyBeanPostProcessorsBeforeInitialization 調用bean的后置處理器進行對處理
i4.5.3>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
對象的初始化方法
i4.5.3.1>:org.springframework.beans.factory.InitializingBean#afterPropertiesSet 調用
InitializingBean的方法
i4.5.3.2>:String initMethodName = mbd.getInitMethodName(); 自定義的初始化方法
i5>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton 把創(chuàng)建好的實
例化好的bean加載緩存中
i6>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance對創(chuàng)建的bean進行后續(xù)的加工
i1:>org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
i2>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
* 轉換對應的beanName 你們可能認為傳入進來的name 不就是beanName么虽惭?
* 傳入進來的可能是別名,也有可能是是factoryBean
* 1)去除factoryBean的修飾符 name="&instA"=====>instA
* 2)取指定的alias所表示的最終beanName 比如傳入的是別名為ia---->指向為instA的bean橡类,那么就返回instA
**/
final String beanName = transformedBeanName(name);
Object bean;
* 設計的精髓
* 檢查實例緩存中對象工廠緩存中是包含對象(從這里返回的可能是實例話好的,也有可能是沒有實例化好的)
* 為什么要這段代碼?
* 因為單實例bean創(chuàng)建可能存主依賴注入的情況,而為了解決循環(huán)依賴問題芽唇,在對象剛剛創(chuàng)建好(屬性還沒有賦值)
* 的時候顾画,就會把對象包裝為一個對象工廠暴露出去(加入到對象工廠緩存中),一但下一個bean要依賴他,就直接可以從緩存中獲取.
//直接從緩存中獲取或者從對象工廠緩存去取匆笤。
// 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 + "'");
}
}
* 若從緩存中的sharedInstance是原始的bean(屬性還沒有進行實例化,那么在這里進行處理)
* 或者是factoryBean 返回的是工廠bean的而不是我們想要的getObject()返回的bean ,就會在這里處理
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
* 為什么spring對原型對象就不能解決循環(huán)依賴的問題了研侣?
* 因為spring ioc對原型對象不進行緩存,所以無法提前暴露對象,每次調用都會創(chuàng)建新的對象.
*
* 比如對象A中的屬性對象B,對象B中有屬性A, 在創(chuàng)建A的時候 檢查到依賴對象B,那么就會返過來創(chuàng)建對象B疚膊,在創(chuàng)建B的過程
* 又發(fā)現(xiàn)依賴對象A,由于是原型對象的义辕,ioc容器是不會對實例進行緩存的 所以無法解決循環(huán)依賴的問題
*
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
獲取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
如果beanDefinitionMap中所有以及加載的bean不包含 本次加載的beanName虾标,那么嘗試取父容器取檢測
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).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);
}
}
如果這里不是做類型檢查寓盗,而是創(chuàng)建bean,這里需要標記一下.
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
合并父 BeanDefinition 與子 BeanDefinition,后面會單獨分析這個方法
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//用來處理bean加載的順序依賴 比如要創(chuàng)建instA 的情況下 必須需要先創(chuàng)建instB
* <bean id="beanA" class="BeanA" depends-on="beanB">
<bean id="beanB" class="BeanB" depends-on="beanA">
創(chuàng)建A之前 需要創(chuàng)建B 創(chuàng)建B之前需要創(chuàng)建A 就會拋出異常
// 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 {
優(yōu)先創(chuàng)建依賴的對象
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
創(chuàng)建bean(單例的 )
// Create bean instance.
if (mbd.isSingleton()) {
創(chuàng)建單實例bean
sharedInstance = getSingleton(beanName, () -> {
在getSingleton房中進行回調用的
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
創(chuàng)建非單實例bean
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);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final 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;
}
}
// Check if required type matches the type of the actual bean instance.
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;
}
i2.2>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton 去緩存中
獲取bean源碼分析
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
去緩存map中獲取以及實例化好的bean對象
Object singletonObject = this.singletonObjects.get(beanName);
緩存中沒有獲取到,并且當前bean是否在正在創(chuàng)建
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
加鎖璧函,防止并發(fā)創(chuàng)建
synchronized (this.singletonObjects) {
保存早期對象緩存中是否有該對象
singletonObject = this.earlySingletonObjects.get(beanName);
早期對象緩存沒有
if (singletonObject == null && allowEarlyReference) {
早期對象暴露工廠緩存(用來解決循環(huán)依賴的)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
調用方法獲早期對象
if (singletonFactory != null) {
放入到早期對象緩存中
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
i2.3>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance
在Bean的生命周期中傀蚌,getObjectForBeanInstance方法是頻繁使用的方法,無論是從緩存中獲取出來的bean還是
根據(jù)scope創(chuàng)建出來的bean,都要通過該方法進行檢查蘸吓。
①:檢查當前bean是否為factoryBean,如果是就需要調用該對象的getObject()方法來返回我們需要的bean對象
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
判斷name為以 &開頭的但是 又不是factoryBean類型的 就拋出異常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
現(xiàn)在我們有了這個bean善炫,它可能是一個普通bean 也有可能是工廠bean
* 1)若是工廠bean,我們使用他來創(chuàng)建實例库继,當如果想要獲取的是工廠實例而不是工廠bean的getObject()對應的bean,我們應該傳
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
加載factoryBean
Object object = null;
if (mbd == null) {
* 如果 mbd 為空箩艺,則從緩存中加載 bean窜醉。FactoryBean 生成的單例 bean 會被緩存
* 在 factoryBeanObjectCache 集合中,不用每次都創(chuàng)建
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
經過前面的判斷艺谆,到這里可以保證 beanInstance 是 FactoryBean 類型的榨惰,所以可以進行類型轉換
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
如果 mbd 為空,則判斷是否存在名字為 beanName 的 BeanDefinition
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
合并我們的bean定義
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
調用 getObjectFromFactoryBean 方法繼續(xù)獲取實例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
=====================================核心方法===========getObjectFromFactoryBean()方法=========================================================
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
* FactoryBean 也有單例和非單例之分静汤,針對不同類型的 FactoryBean琅催,這里有兩種處理方式:
* 1. 單例 FactoryBean 生成的 bean 實例也認為是單例類型。需放入緩存中虫给,供后續(xù)重復使用
* 2. 非單例 FactoryBean 生成的 bean 實例則不會被放入緩存中藤抡,每次都會創(chuàng)建新的實例
if (factory.isSingleton() && containsSingleton(beanName)) {
加鎖,防止重復創(chuàng)建 可以使用緩存提高性能
synchronized (getSingletonMutex()) {
從緩存中獲取
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
沒有獲取到抹估,使用factoryBean的getObject()方法去獲取對象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
調用ObjectFactory的后置處理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
=====================================doGetObjectFromFactoryBean()作用====================================================================
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
安全檢查
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
調用工廠bean的getObject()方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
================================================postProcessObjectFromFactoryBean(object, beanName);===========================
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
i2.6>:org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition 將
bean定義轉為RootBeanDifination
合并父子bean定義
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
去合并的bean定義緩存中 判斷當前的bean是否合并過
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
沒有合并缠黍,調用合并分方法
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
根據(jù)beanName獲取到當前的bean定義信息
============================getBeanDefinition===========================
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
去緩存中獲取一次bean定義
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
嘗試沒有獲取到
if (mbd == null) {
當前bean定義是否有父bean
if (bd.getParentName() == null) {
轉為rootBeanDefinaition 然后深度克隆返回
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
定義一個父的bean定義
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
獲取父bena的名稱
String parentBeanName = transformedBeanName(bd.getParentName());
/** 判斷父類 beanName 與子類 beanName 名稱是否相同。若相同棋蚌,則父類 bean 一定
* 在父容器中嫁佳。原因也很簡單,容器底層是用 Map 緩存 <beanName, bean> 鍵值對
* 的谷暮。同一個容器下蒿往,使用同一個 beanName 映射兩個 bean 實例顯然是不合適的。
* 有的朋友可能會覺得可以這樣存儲:<beanName, [bean1, bean2]> 湿弦,似乎解決了
* 一對多的問題瓤漏。但是也有問題,調用 getName(beanName) 時,到底返回哪個 bean
* 實例好呢推汽?
*/
if (!beanName.equals(parentBeanName)) {
* 這里再次調用 getMergedBeanDefinition灭袁,只不過參數(shù)值變?yōu)榱?* parentBeanName,用于合并父 BeanDefinition 和爺爺輩的
* BeanDefinition饥漫。如果爺爺輩的 BeanDefinition 仍有父
* BeanDefinition,則繼續(xù)合并
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
獲取父容器
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
從父容器獲取父bean的定義 //若父bean中有父bean 存儲遞歸合并
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
以父 BeanDefinition 的配置信息為藍本創(chuàng)建 RootBeanDefinition罗标,也就是“已合并的 BeanDefinition”
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
用子 BeanDefinition 中的屬性覆蓋父 BeanDefinition 中的屬性
mbd.overrideFrom(bd);
}
/若之前沒有定義,就把當前的設置為單例的
// Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
緩存合并后的 BeanDefinition
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
i2.8>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton根據(jù)scope
的添加來創(chuàng)建bean
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
//從緩存中獲取對象
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 + "'");
}
//打標.....把正在創(chuàng)建的bean 的標識設置為ture singletonsCurrentlyInDestruction
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//調用單實例bean的創(chuàng)建
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
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);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
=========================singletonObject = singletonFactory.getObject()=======================>createBeansharedInstance =
getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
==============================================addSingleton(beanName, singletonObject);=================
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//加入到緩存
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
//從早期對象緩存和解決依賴緩存中移除..................
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
i3>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//根據(jù)bean定義和beanName解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//給bean的后置處理器一個機會來生成一個代理對象返回,在aop模塊進行詳細講解
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);
}
//真正進行主要的業(yè)務邏輯方法來進行創(chuàng)建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
i4:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 真正
的創(chuàng)建bean的邏輯
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//調用構造方法創(chuàng)建bean的實例()
if (instanceWrapper == null) {
/**
* 如果存在工廠方法則使用工廠方法進行初始化
* 一個類有多個構造函數(shù)庸队,每個構造函數(shù)都有不同的參數(shù),所以需要根據(jù)參數(shù)鎖定構造 函數(shù)并進行初始化闯割。
* 如果既不存在工廠方法也不存在帶有參數(shù)的構造函數(shù)彻消,則使用默認的構造函數(shù)進行 bean 的實例化
* */
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
/*
bean的后置處理器
*bean 合并后的處理, Autowired 注解正是通過此方法實現(xiàn)諸如類型的預解析宙拉。
**/
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
//判斷當前bean是否需要暴露到 緩存對象中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//暴露早期對象到緩存中用于解決依賴的宾尚。
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//為當前的bean 填充屬性,發(fā)現(xiàn)依賴等....解決循環(huán)依賴就是在這個地方
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//調用bean的后置處理器以及 initionalBean和自己自定義的方法進行初始化
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án)依賴 earlySingletonReference才會為空
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//檢查當前的Bean 在初始化方法中沒有被增強過(代理過)
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//注冊 DisposableBean谢澈。 如果配置了 destroy-method煌贴,這里需要注冊以便于在銷毀時候調用御板。
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
i4.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
調用構造函數(shù)創(chuàng)建對象
===============================createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args)===========================
因為一個類可能有多個構造函數(shù),所以需要根據(jù)配置文件中配置的參數(shù)或者傳入的參數(shù)確定最終調用的構造函數(shù)牛郑。因為判斷過程會比較消耗性能所以Spring會將解析稳吮、確定好的構造函數(shù)緩存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。在下次創(chuàng)建相同bean的會直接從RootBeanDefinition中的屬性resolvedConstructorOrFactoryMethod緩存的值獲取井濒,避免再次解析
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
///工廠方法不為空則使工廠方法初始化策略 也就是bean的配置過程中設置了factory-method方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
// 如果已緩存的解析的構造函數(shù)或者工廠方法不為空灶似,則可以利用構造函數(shù)解析
// 因為需要根據(jù)參數(shù)確認到底使用哪個構造函數(shù),該過程比較消耗性能瑞你,所有采用緩存機制(緩存到bean定義中)
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//從bean定義中解析出對應的構造函數(shù)
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//已經解析好了酪惭,直接注入即可
if (resolved) {
if (autowireNecessary) {
//autowire 自動注入,調用構造函數(shù)自動注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默認的構造函數(shù)
return instantiateBean(beanName, mbd);
}
}
//根據(jù)beanClass和beanName去bean的后置處理器中獲取構造方法(SmartInstantiationAwareBeanPostProcessor ----AutowiredAnnotationBeanPostProcessor)
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//使用
return instantiateBean(beanName, mbd);
}
=======================================提前暴露對象=========================================================
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//把bean 作為objectFactory暴露出來..........
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
/**
* 在配置文件中是我們使用的@Bean的形式都是通過工廠方法的形式來實例化對象
*
* */
====================================autowireConstructor(beanName, mbd, ctors, args);很復雜 很復雜 =====================================================
1者甲、autowireConstructor(帶參)
對于實例的創(chuàng)建春感,Spring分為通用的實例化(默認無參構造函數(shù)),以及帶有參數(shù)的實例化
下面代碼是帶有參數(shù)情況的實例化虏缸。因為需要確定使用的構造函數(shù)鲫懒,所以需要有大量工作花在根據(jù)參數(shù)個數(shù)、類型來確定構造函數(shù)上(因為帶參public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
//用于包裝bean實例的
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
//定義一個參數(shù)用來保存 使用的構造函數(shù)
Constructor<?> constructorToUse = null;
//定義一個參數(shù)用來保存 使用的參數(shù)持有器
ArgumentsHolder argsHolderToUse = null;
//用于保存 使用的參數(shù)
Object[] argsToUse = null;
//判斷傳入的參數(shù)是不是空
if (explicitArgs != null) {
//賦值給argsToUse 然后執(zhí)行使用
argsToUse = explicitArgs;
}
//傳入進來的是空,需要從配置文件中解析出來
else {
//存解析的參數(shù)
Object[] argsToResolve = null;
//加鎖
synchronized (mbd.constructorArgumentLock) {
//從緩存中獲取解析出來的構造參數(shù)
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
//緩存中有構造方法
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
//從緩存中獲取解析的參數(shù)
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//沒有緩存的參數(shù)刽辙,就需要獲取配置文件中配置的參數(shù)
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//緩存中有構造器參數(shù)
if (argsToResolve != null) {
//解析參數(shù)類型窥岩, 如給定方法的構造函數(shù) A( int , int ) 則通過此方法后就會把配置中的 //( ”1”,”l”)轉換為 (1 , 1)
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//如果沒有緩存宰缤,就需要從構造函數(shù)開始解析
if (constructorToUse == null) {
//是否需要解析構造函數(shù)
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
//用來保存getBeans傳入進來的參數(shù)的個數(shù)
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//從bean定義中解析出來構造參數(shù)的對象
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//計算出構造參數(shù)參數(shù)的個數(shù)
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//如果傳入的構造器數(shù)組不為空颂翼,就使用傳入的構造器參數(shù),否則通過反射獲取class中定義的構造器
Constructor<?>[] candidates = chosenCtors;
//傳入的構造參數(shù)為空
if (candidates == null) {
//解析出對應的bean的class
Class<?> beanClass = mbd.getBeanClass();
try {
//獲取構造方法
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
////給構造函數(shù)排序慨灭,public構造函數(shù)優(yōu)先朦乏、參數(shù)數(shù)量降序排序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
//不確定的構造函數(shù)
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
//根據(jù)從bean定義解析出來的參數(shù)個數(shù)來推算出構造函數(shù)
//循環(huán)所有的構造函數(shù) 查找合適的構造函數(shù)
for (Constructor<?> candidate : candidates) {
//獲取正在循環(huán)的構造函數(shù)的個數(shù)
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
//如果找到了已經構造函數(shù),并且已經確定的構造函數(shù)的參數(shù)個數(shù)>正在當前循環(huán)的 那么就直接返回(candidates參break;
}
//參數(shù)個數(shù)不匹配 直接進入下一個循環(huán)
if (paramTypes.length < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
//從bean定義中解析的構造函數(shù)的參數(shù)對象
if (resolvedValues != null) {
try {
//從注解 @ConstructorProperties獲取參數(shù)名稱
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
//沒有獲取到
if (paramNames == null) {
//去容器中獲取一個參數(shù)探測器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//通過參數(shù)探測器去探測當前正在循環(huán)的構造參數(shù)
paramNames = pnd.getParameterNames(candidate);
}
}
///根據(jù)參數(shù)名稱和數(shù)據(jù)類型創(chuàng)建參數(shù)持有器
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<UnsatisfiedDependencyException>();
}
causes.add(ex);
continue;
}
}
else {
//解析出來的參數(shù)個數(shù)和從外面?zhèn)鬟f進來的個數(shù)不相等 進入下一個循環(huán)
if (paramTypes.length != explicitArgs.length) {
continue;
}
//把外面?zhèn)鬟f進來的參數(shù)封裝為一個參數(shù)持有器
argsHolder = new ArgumentsHolder(explicitArgs);
}
///探測是否有不確定性的構造函數(shù)存在, 例如不同構造函數(shù)的參數(shù)為父子關系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
//因為不同構造函數(shù)的參數(shù)個數(shù)相同氧骤,而且參數(shù)類型為父子關系呻疹,所以需要找出類型最符合的一個構造函數(shù)
//Spring用一種權重的形式來表示類型差異程度,差異權重越小越優(yōu)先
if (typeDiffWeight < minTypeDiffWeight) {
//當前構造函數(shù)最為匹配的話筹陵,清空先前ambiguousConstructors列表
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
////存在相同權重的構造器刽锤,將構造器添加到一個ambiguousConstructors列表變量中
//注意,這時候constructorToUse 指向的仍是第一個匹配的構造函數(shù)
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
//還是沒有找到構造函數(shù) 就拋出異常
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
//把解析出來的構造函數(shù)加入到緩存中
if (explicitArgs == null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
//調用構造函數(shù)進行反射創(chuàng)建
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
//獲取生成實例策略類調用實例方法
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
========================instantiate=========================================
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
if (bd.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
}
//調用反射創(chuàng)建
return BeanUtils.instantiateClass(ctor, args);
}
else {
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
i4.2>:判斷是否需要提早暴露對象(mbd.isSingleton() && this.allowCircularReferences && i
sSingletonCurrentlyInCreation(beanName));
i4.3>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory
暴露對象解決循環(huán)依賴
//判斷當前bean是否需要暴露到 緩存對象中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//暴露早期對象到緩存中用于解決依賴的。
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
//暴露早期對象到緩存中用于解決依賴的惶翻。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
i4.4>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean 給
創(chuàng)建的bean進行賦值
//我們看這個方法沒多長是不是姑蓝?但是調用的細節(jié)比較復雜,不過我們看IOC 源碼 需要抓主干鹅心,有些方式我們完全可以看做
//為一個黑盒方法,只要知道他是干什么的 不需要去每一行 每一行代碼都去了解.....
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
//從bean定義中獲取屬性列表
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
/*
* 在屬性被填充前吕粗,給 InstantiationAwareBeanPostProcessor 類型的后置處理器一個修改
* bean 狀態(tài)的機會。官方的解釋是:讓用戶可以自定義屬性注入旭愧。比如用戶實現(xiàn)一
* 個 InstantiationAwareBeanPostProcessor 類型的后置處理器颅筋,并通過
* postProcessAfterInstantiation 方法向 bean 的成員變量注入自定義的信息宙暇。當然,如果無
* 特殊需求议泵,直接使用配置中的信息注入即可占贫。
*/
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
//上面返回為flase 表示你已經通過自己寫的InstantiationAwareBeanPostProcessor 類型的處理器已經設置過bean的屬性值了,不需要springif (!continueWithPropertyPopulation) {
return;
}
/**
* 判斷注入模型是不是byName 或者是byType的
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
//封裝屬性列表
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 若是基于byName自動轉入的
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//計入byType自動注入的
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//把處理過的 屬性覆蓋原來的
pvs = newPvs;
}
/**
* 判斷有沒有InstantiationAwareBeanPostProcessors類型的處理器
*
* */
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
/**
* 判斷是否需要依賴檢查(默認是0)
* DEPENDENCY_CHECK_NONE(0) 不做檢查
* DEPENDENCY_CHECK_OBJECTS(1) 只檢查對象引用
* DEPENDENCY_CHECK_SIMPLE(2)檢查簡單屬性
* DEPENDENCY_CHECK_ALL(3)檢查所有的
* */
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
/*
* 這里又是一種后置處理,用于在 Spring 填充屬性到 bean 對象前先口,對屬性的值進行相應的處理型奥,
* 比如可以修改某些屬性的值。這時注入到 bean 中的值就不是配置文件中的內容了碉京,
* 而是經過后置處理器修改后的內容
*/
if (hasInstAwareBpps || needsDepCheck) {
//過濾出所有需要進行依賴檢查的屬性編輯器 并且進行緩存起來
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
//通過后置處理器來修改屬性
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
//需要檢查的化 厢汹,那么需要檢查依賴
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//設置屬性到beanWapper中
applyPropertyValues(beanName, mbd, bw, pvs);
}
//上訴代碼的作用
1)獲取了bw的屬性列表
2)在屬性列表中被填充的之前,通過InstantiationAwareBeanPostProcessor 對bw的屬性進行修改
3)判斷自動裝配模型來判斷是調用byTypeh還是byName
4)再次應用后置處理谐宙,用于動態(tài)修改屬性列表 pvs 的內容
5)把屬性設置到bw中
我們就來分析=====================================autowireByName=======================================
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
/**
* spring認為的簡單屬性
* 1. CharSequence 接口的實現(xiàn)類烫葬,比如 String
* 2. Enum
* 3. Date
* 4. URI/URL
* 5. Number 的繼承類,比如 Integer/Long
* 6. byte/short/int... 等基本類型
* 7. Locale
* 8. 以上所有類型的數(shù)組形式凡蜻,比如 String[]搭综、Date[]、int[] 等等
* 不包含在當前bean的配置文件的中屬性 !pvs.contains(pd.getName()
* */
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
//循環(huán)解析出來的屬性名稱
for (String propertyName : propertyNames) {
//若當前循環(huán)的屬性名稱是當前bean中定義的屬性
if (containsBean(propertyName)) {
//去ioc中獲取指定的bean對象
Object bean = getBean(propertyName);
//并且設置到當前bean中的pvs中
pvs.add(propertyName, bean);
//注冊屬性依賴
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
我們就來分析=====================================autowireByType=======================================
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//獲取自定義類型的轉換器
TypeConverter converter = getCustomTypeConverter();
//沒有獲取到 把bw賦值給轉換器(BeanWrapper實現(xiàn)了 TypeConverter接口 )
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
//獲取非簡單bean的屬性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
//循環(huán)屬性
for (String propertyName : propertyNames) {
try {
//bw中是否有該屬性的描述器
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
//若是Object的屬性 不做解析
if (Object.class != pd.getPropertyType()) {
/*
* 獲取 setter 方法(write method)的參數(shù)信息划栓,比如參數(shù)在參數(shù)列表中的
* 位置兑巾,參數(shù)類型,以及該參數(shù)所歸屬的方法等信息
*/
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
// 創(chuàng)建依賴描述對象
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//過程比較復雜忠荞,先把這里看成一個黑盒闪朱,我們只要知道這個方法可以幫我們解析出合適的依賴即可
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
/// 將解析出的 bean 存入到屬性值列表(pvs)中
pvs.add(propertyName, autowiredArgument);
}
//循環(huán)調用,注冊到bean的依賴中
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
================================applyPropertyValues(beanName, mbd, bw, pvs);=======================================================
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs == null || pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) { //如果屬性列表 pvs 被轉換過钻洒,則直接返回即可
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
//獲取bw中的屬性列表
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
//獲取自定義的轉化器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//獲取bean定義的值解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
boolean resolveNecessary = false;
//循環(huán)屬性集合
for (PropertyValue pv : original) {
//當前的屬性值被轉化過 添加到
if (pv.isConverted()) {
保存到集合中去
deepCopy.add(pv);
}
else {
//屬性名
String propertyName = pv.getName();
//原始屬性值
Object originalValue = pv.getValue();
//就是在該方法上來解決循環(huán)依賴的 解析出來的值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
//把解析出來的賦值給轉換的值
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
// 對屬性值的類型進行轉換奋姿,比如將 String 類型的屬性值 "123" 轉為 Integer 類型的 123
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
//// 將 convertedValue 設置到 pv 中,后續(xù)再次創(chuàng)建同一個 bean 時素标,就無需再次進行轉換了
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
/**
* 如果原始值 originalValue 是 TypedStringValue称诗,且轉換后的值
* convertedValue 不是 Collection 或數(shù)組類型,則將轉換后的值存入到 pv 中头遭。
*/
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
// 將所有的屬性值設置到 bean 實例中
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
===============================valueResolver.resolveValueIfNecessary=====================================
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
public Object resolveValueIfNecessary(Object argName, Object value) {
//判斷解析的值是不是 運行時bean的引用
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
//解析引用
return resolveReference(argName, ref);
}
//若value 是RuntimeBeanNameReference
else if (value instanceof RuntimeBeanNameReference) {
String refName = ((RuntimeBeanNameReference) value).getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (!this.beanFactory.containsBean(refName)) {
throw new BeanDefinitionStoreException(
"Invalid bean name '" + refName + "' in bean reference for " + argName);
}
return refName;
}
//是BeanDefinitionHolder
else if (value instanceof BeanDefinitionHolder) {
// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
}
//BeanDefinition
else if (value instanceof BeanDefinition) {
// Resolve plain BeanDefinition, without contained name: use dummy name.
BeanDefinition bd = (BeanDefinition) value;
String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
ObjectUtils.getIdentityHexString(bd);
return resolveInnerBean(argName, innerBeanName, bd);
}
//處理array的
else if (value instanceof ManagedArray) {
// May need to resolve contained runtime references.
ManagedArray array = (ManagedArray) value;
Class<?> elementType = array.resolvedElementType;
if (elementType == null) {
String elementTypeName = array.getElementTypeName();
if (StringUtils.hasText(elementTypeName)) {
try {
elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
array.resolvedElementType = elementType;
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error resolving array type for " + argName, ex);
}
}
else {
elementType = Object.class;
}
}
return resolveManagedArray(argName, (List<?>) value, elementType);
}
else if (value instanceof ManagedList) {
// May need to resolve contained runtime references.
return resolveManagedList(argName, (List<?>) value);
}
else if (value instanceof ManagedSet) {
// May need to resolve contained runtime references.
return resolveManagedSet(argName, (Set<?>) value);
}
else if (value instanceof ManagedMap) {
// May need to resolve contained runtime references.
return resolveManagedMap(argName, (Map<?, ?>) value);
}
else if (value instanceof ManagedProperties) {
Properties original = (Properties) value;
Properties copy = new Properties();
for (Map.Entry<Object, Object> propEntry : original.entrySet()) {
Object propKey = propEntry.getKey();
Object propValue = propEntry.getValue();
if (propKey instanceof TypedStringValue) {
propKey = evaluate((TypedStringValue) propKey);
}
if (propValue instanceof TypedStringValue) {
propValue = evaluate((TypedStringValue) propValue);
}
copy.put(propKey, propValue);
}
return copy;
}
else if (value instanceof TypedStringValue) {
// Convert value to target type here.
TypedStringValue typedStringValue = (TypedStringValue) value;
Object valueObject = evaluate(typedStringValue);
try {
Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
if (resolvedTargetType != null) {
return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
}
else {
return valueObject;
}
}
catch (Throwable ex) {
// Improve the message by showing the context.
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Error converting typed String value for " + argName, ex);
}
}
else {
return evaluate(value);
}
}
==============================================真正的解析bean的依賴引用=========================================
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
//獲取bean的引用的名稱
String refName = ref.getBeanName();
//調用值解析器來解析bean的名稱
refName = String.valueOf(doEvaluate(refName));
//判斷父容器是否能夠解析
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
return this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
//解析出來的refName 去容器中獲取bean(getBean->doGetBean寓免。。计维。袜香。。鲫惶。蜈首。。。欢策。吆寨。)
Object bean = this.beanFactory.getBean(refName);
//保存到緩存中
this.beanFactory.registerDependentBean(refName, this.beanName);
return bean;
}
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
i4.5>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean對
bean進行初始化
初始化方法
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//調用bean實現(xiàn)的 XXXAware接口
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//調用bean的后置處理器的before方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//調用initianlBean的方法和自定義的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//調用Bean的后置處理器的post方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
i4.5.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods 調用XXAware接口
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) { //判斷bean是否實現(xiàn)了Aware接口
if (bean instanceof BeanNameAware) { //實現(xiàn)了BeanNameAware接口
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) { //實現(xiàn)了BeanClassLoaderAware接口
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) { //實現(xiàn)了BeanFactoryAware接口
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
/
i4.5.2>applyBeanPostProcessorsBeforeInitialization 調用bean的后置處理器進行對處理
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//調用所有的后置處理器的before的方法
result = processor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
i4.5.3>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods 對象的初始化方法
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
//判斷你的bean 是否實現(xiàn)了 InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//調用了InitializingBean的afterPropertiesSet()方法
((InitializingBean) bean).afterPropertiesSet();
}
}
//調用自己在配置bean的時候指定的初始化方法
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
i5>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton 把創(chuàng)建好的實
例化好的bean加載緩存中
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
i6>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance對創(chuàng)建的
bean進行后續(xù)的加工