// 方法位於AbstractBeanFactory.java
public Object getBean(String name) throws BeansException {
// getBean 是一個空殼方法,全部的邏輯都封裝在 doGetBean 方法中
return doGetBean(name, null, null, false);
}
複製代碼
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
/*
* 經過 name 獲取 beanName。這裏不使用 name 直接做爲 beanName 有兩點緣由:
* 1. 若是 name 是 alias ,則獲取對應映射的 beanName 。
* 2. 剝離工廠引用前綴&
*/
final String beanName = transformedBeanName(name);
Object bean;
/*
* 從緩存中或者實例工廠中獲取 Bean 對象
* 從緩存中獲取單例 bean。Spring 是使用 Map 做爲 beanName 和 bean 實例的緩存的,因此這
* 裏暫時能夠把 getSingleton(beanName) 等價於 beanMap.get(beanName)。固然,實際的
* 邏輯並不是如此簡單,後面再細說。
*/
Object sharedInstance = getSingleton(beanName);
/*
* 若是 sharedInstance = null代表這個實例還沒建立。
* BeanFactory 只會在調用 getBean 獲取 bean 時再實例化,也就是懶加載。
* BeanFactory 不會屢次實例化單例 bean。
*/
if (sharedInstance != null && args == null) {
//記錄日誌 沒啥可說的
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/*
* 完成 FactoryBean 的相關處理,並用來獲取 FactoryBean 的處理結果
* 若是 sharedInstance 是普通的單例 bean,下面的方法會直接返回。但若是
* sharedInstance 是 FactoryBean 類型的,則需調用 getObject 工廠方法獲取真正的bean 實例。
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
/*
* sharedInstance 爲空,此時 beanName 對應的 bean 實例可能還未建立。也有可能父容器裏已經實例化,須要先去父容器查找 這裏有些不明白,先標註下而後後續查看
*/
else {
// BeanFactory 不緩存 Prototype 類型的 bean ,Spring 只解決單例模式下得循環依賴,在原型模式下若是存在循環依賴則會拋出異常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 若是 sharedInstance = null,則到父容器中查找 bean 實例 getParentBeanFactory 後續在研究
BeanFactory parentBeanFactory = getParentBeanFactory();
//containsBeanDefinition 方法實際就是判斷 org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionMap 是否有key beanName
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 獲取 name 對應的 beanName,若是 name 是以 & 字符開頭,則返回 & + beanName
String nameToLookup = originalBeanName(name);
// 根據 args 是否爲空,以決定調用父容器哪一個方法獲取 bean
if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 合併父 BeanDefinition 與子 BeanDefinition,後面會單獨分析這個方法
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 檢查是否有 dependsOn 依賴,若是有則先初始化所依賴的 bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
/*
* 檢測是否存在 depends-on 循環依賴,若存在則拋異常。好比 A 依賴 B,
* B 又依賴 A,他們的配置以下:
* <bean id="beanA" class="BeanA" depends-on="beanB">
* <bean id="beanB" class="BeanB" depends-on="beanA">
*
* beanA 要求 beanB 在其以前被建立,但 beanB 又要求 beanA 先於它
* 建立。這個時候造成了循環,對於 depends-on 循環,Spring 會直接
* 拋出異常
*/
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 註冊依賴記錄
registerDependentBean(dep, beanName);
try {
// 加載 depends-on 依賴
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 建立 bean 實例
if (mbd.isSingleton()) {
/*
* 這裏並無直接調用 createBean 方法建立 bean 實例,而是經過
* getSingleton(String, ObjectFactory) 方法獲取 bean 實例。
* getSingleton(String, ObjectFactory) 方法會在內部調用
* ObjectFactory 的 getObject() 方法建立 bean,並會在建立完成後,
* 將 bean 放入緩存中。關於 getSingleton 方法的分析,本文先不展開,我會在
* 後面的文章中進行分析
*/
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 建立 bean 實例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
// 若是 bean 是 FactoryBean 類型,則調用工廠方法獲取真正的 bean 實例。不然直接返回 bean 實例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 建立 prototype 類型的 bean 實例
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 建立其餘類型的 bean 實例
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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 && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 返回 bean
return (T) bean;
}
複製代碼
主要步驟java
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
複製代碼
/**
* beanName 的緩存
*/
private static final Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();
/**
* 去除 FactoryBean 的修飾符 & 若是 name 以 「&」 爲前綴,那麼會去掉該 "&" 。
* 例如,name = "&HelloService" ,則會是 name = "HelloService"。
*/
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { // BeanFactory.FACTORY_BEAN_PREFIX = &
return name;
}
// computeIfAbsent 方法,分紅兩種狀況:
// 1. 未存在,則進行計算執行,並將結果添加到緩存、
// 2. 已存在,則直接返回,無需計算。
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
//BeanFactory.FACTORY_BEAN_PREFIX = "&"
} while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
複製代碼
<bean id="hello" class="service.Hello"/>
<alias name="hello" alias="aliasA"/>
<alias name="aliasA" alias="aliasB"/>
複製代碼
// alias -> beanName 的緩存
private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
/*
* 循環,從 aliasMap 中,獲取到最終的 beanName
*/
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
複製代碼
/** singleton 緩存map 格式爲 bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** singleton factory 緩存 map, 格式爲 bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
/** 建立中的bean */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
/** Names of beans currently excluded from in creation checks */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
/**
* allowEarlyReference 表示是否容許其餘 bean 引用
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 從 singletonObjects 獲取實例,singletonObjects 中緩存的實例都是徹底實例化好的 bean,能夠直接使用
Object singletonObject = this.singletonObjects.get(beanName);
/*
* 若是 singletonObject = null,代表還沒建立,或者還沒徹底建立好。
*/
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 從 earlySingletonObjects 中獲取提早曝光的 bean,用於處理循環引用
singletonObject = this.earlySingletonObjects.get(beanName);
// 若是若是 singletonObject = null,且容許提早曝光 bean 實例,則從相應的 ObjectFactory 獲取一個原始的(raw)bean(還沒有填充屬性)
if (singletonObject == null && allowEarlyReference) {
// 獲取相應的工廠類
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 提早曝光 bean 實例,用於解決循環依賴
singletonObject = singletonFactory.getObject();
// 放入緩存中,若是還有其餘 bean 依賴當前 bean,其餘 bean 能夠直接從 earlySingletonObjects 取結果
this.earlySingletonObjects.put(beanName, singletonObject);
//移除bean factory 由於已經出事花了一個原始bean放入 earlySingletonObjects
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
複製代碼
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
複製代碼
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 若是 name 以 & 開頭,但 beanInstance 卻不是 FactoryBean,拋出異常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
/**
* 1 beanInstance 是 FactoryBean 須要調用 工廠方法生成bean
* 2 beanInstance 是一個普通bean 直接返回
*/
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
//若是 mbd 爲空,則從緩存中加載 bean。FactoryBean 生成的單例 bean 會被緩存 在 factoryBeanObjectCache 集合中,不用每次都建立
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 到這一步確定是FactoryBean
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// 若是mbd is null 則判斷是否存在 beanname 的 BeanDefinition,若存在 合併
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
複製代碼
/**
* FactoryBean 也有單例和原型之分
* 針對單例FactoryBean 生成bean 也默認是單例模式,須要放入緩存
* 非單例的FactoryBean 生成的bean 則不會放入緩存
* @param factory
* @param beanName
* @param shouldPostProcess 對bean 進行後置處理
* @return
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//若是factory 是單例模式
if (factory.isSingleton() && this.containsSingleton(beanName)) {
synchronized(this.getSingletonMutex()) {
//緩存中獲取bean
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//使用工廠方法建立bean
object = this.doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
} else {
if (shouldPostProcess) {
// singletonsCurrentlyInCreation 是否已有該bean Name, 若是有直接返回
if (this.isSingletonCurrentlyInCreation(beanName)) {
return object;
}
this.beforeSingletonCreation(beanName);
try {
//後置處理
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var14) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var14);
} finally {
this.afterSingletonCreation(beanName);
}
}
// singletonObjects map 是否包含 beanName
if (this.containsSingleton(beanName)) {
//若是包含則 把 FactoryBean 建立的bean 緩存到 factoryBeanObjectCache
//factoryBeanObjectCache 定義於 org.springframework.beans.factory.support.FactoryBeanRegistrySupport
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
} else {
//非單例模式 直接經過工廠方法獲取
Object object = this.doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", var17);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
//這塊沒太懂
if (System.getSecurityManager() != null) {
AccessControlContext acc = this.getAccessControlContext();
try {
object = AccessController.doPrivileged(factory::getObject, acc);
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
//直接經過工廠方法獲取
object = factory.getObject();
}
} catch (FactoryBeanNotInitializedException var7) {
throw new BeanCurrentlyInCreationException(beanName, var7.toString());
} catch (Throwable var8) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
}
if (object == null) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
複製代碼
待完善中spring