Spring特性介紹-bean注冊(cè)和注入覆蓋

1.注冊(cè)

//存儲(chǔ)注冊(cè)的俄BeanDefinition

private final Map beanDefinitionMap = new ConcurrentHashMap();

//向IoC容器注冊(cè)解析的BeanDefiniton

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

throws BeanDefinitionStoreException {

????Assert.hasText(beanName, "Bean name must not be empty");

????Assert.notNull(beanDefinition, "BeanDefinition must not be null");

? ? //校驗(yàn)解析的BeanDefiniton,判斷

????if (beanDefinition instanceof AbstractBeanDefinition) {

????try {

????????((AbstractBeanDefinition) beanDefinition).validate();

????}catch (BeanDefinitionValidationException ex) {

????????throw new ? ?

????????BeanDefinitionStoreException(beanDefinition.getResourceDescription(),

????????beanName,"Validation of bean definition failed", ex);

????}

}

//注冊(cè)的過(guò)程中需要線程同步,以保證數(shù)據(jù)的一致性

synchronized (this.beanDefinitionMap) {

????Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);

}

//檢查是否有同名的BeanDefinition已經(jīng)在IoC容器中注冊(cè),如果已經(jīng)注冊(cè),

//并且不允許覆蓋已注冊(cè)的Bean,則拋出注冊(cè)失敗異常

if (oldBeanDefinition != null) {

????if (!this.allowBeanDefinitionOverriding) {

????????throw new

? ? ? ?BeanDefinitionStoreException(beanDefinition.getResourceDescription(), ????????

? ? ? ?beanName,"Cannot register bean definition [" + beanDefinition + "] for bean '" +?

? ? ? beanName +"': There is already [" + oldBeanDefinition + "] bound.");

}else {

????//如果允許覆蓋,則同名的Bean,后注冊(cè)的覆蓋先注冊(cè)的

????????if (this.logger.isInfoEnabled()) {

????????????this.logger.info("Overriding bean definition for bean '" + beanName +"': ????

????????????replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

????????}????

????}

}

//IoC容器中沒(méi)有已經(jīng)注冊(cè)同名的Bean,按正常注冊(cè)流程注冊(cè)

else {

????this.beanDefinitionNames.add(beanName);

? ? this.frozenBeanDefinitionNames = null;

}

????????this.beanDefinitionMap.put(beanName, beanDefinition);

????????//重置所有已經(jīng)注冊(cè)過(guò)的BeanDefinition的緩存

????????resetBeanDefinition(beanName);

????}

}?

2.注入

protected T doGetBean(final String name, final Class requiredType,?

????????final Object[] args, boolean typeCheckOnly)throws BeansException {

????//根據(jù)指定的名稱獲取被管理Bean的名稱,剝離指定名稱中對(duì)容器的相關(guān)依賴

????//如果指定的是別名,將別名轉(zhuǎn)換為規(guī)范的Bean名稱

????final String beanName = transformedBeanName(name);

????Object bean;

????//先從緩存中取是否已經(jīng)有被創(chuàng)建過(guò)的單態(tài)類型的Bean,對(duì)于單態(tài)模式的Bean整

? ? //個(gè)IoC容器中只創(chuàng)建一次,不需要重復(fù)創(chuàng)建

????Object sharedInstance = getSingleton(beanName);

????//IoC容器創(chuàng)建單態(tài)模式Bean實(shí)例對(duì)象

????if (sharedInstance != null && args == null) {

????????if (logger.isDebugEnabled()) {

????????//如果指定名稱的Bean在容器中已有單態(tài)模式的Bean被創(chuàng)建,直接返回

????????//已經(jīng)創(chuàng)建的Bean

????????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 + "'");

????????}

}

????//獲取給定Bean的實(shí)例對(duì)象,主要是完成FactoryBean的相關(guān)處理

????//注意:BeanFactory是管理容器中Bean的工廠,而FactoryBean是

????//創(chuàng)建創(chuàng)建對(duì)象的工廠Bean,兩者之間有區(qū)別

????bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);

}else {

//緩存沒(méi)有正在創(chuàng)建的單態(tài)模式Bean

//緩存中已經(jīng)有已經(jīng)創(chuàng)建的原型模式Bean,但是由于循環(huán)引用的問(wèn)題導(dǎo)致實(shí)

//例化對(duì)象失敗

if (isPrototypeCurrentlyInCreation(beanName)) {

????throw new BeanCurrentlyInCreationException(beanName);

}

//對(duì)IoC容器中是否存在指定名稱的BeanDefinition進(jìn)行檢查,首先檢查是否

//能在當(dāng)前的BeanFactory中獲取的所需要的Bean,如果不能則委托當(dāng)前容器

//的父級(jí)容器去查找,如果還是找不到則沿著容器的繼承體系向父級(jí)容器查找

BeanFactory parentBeanFactory = getParentBeanFactory();

//當(dāng)前容器的父級(jí)容器存在,且當(dāng)前容器中不存在指定名稱的Bean

if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

????//解析指定Bean名稱的原始名稱

????String nameToLookup = originalBeanName(name);

????if (args != null) {

????//委派父級(jí)容器根據(jù)指定名稱和顯式的參數(shù)查找

????return (T) parentBeanFactory.getBean(nameToLookup, args);

}

else {

????//委派父級(jí)容器根據(jù)指定名稱和類型查找

????return parentBeanFactory.getBean(nameToLookup, requiredType);

}

}

//創(chuàng)建的Bean是否需要進(jìn)行類型驗(yàn)證,一般不需要

if (!typeCheckOnly) {

????//向容器標(biāo)記指定的Bean已經(jīng)被創(chuàng)建

????markBeanAsCreated(beanName);????

}

//根據(jù)指定Bean名稱獲取其父級(jí)的Bean定義,主要解決Bean繼承時(shí)子類

//合并父類公共屬性問(wèn)題

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd, beanName, args);

//獲取當(dāng)前Bean所有依賴Bean的名稱

String[] dependsOn = mbd.getDependsOn();

//如果當(dāng)前Bean有依賴Bean

if (dependsOn != null) {

for (String dependsOnBean : dependsOn) {

//遞歸調(diào)用getBean方法,獲取當(dāng)前Bean的依賴Bean

????getBean(dependsOnBean);

????//把被依賴Bean注冊(cè)給當(dāng)前依賴的Bean

????registerDependentBean(dependsOnBean, beanName);

????}

}

//創(chuàng)建單態(tài)模式Bean的實(shí)例對(duì)象

if (mbd.isSingleton()) {

//這里使用了一個(gè)匿名內(nèi)部類,創(chuàng)建Bean實(shí)例對(duì)象,并且注冊(cè)給所依賴的對(duì)象

????sharedInstance = getSingleton(beanName, new ObjectFactory() {

????public Object getObject() throws BeansException {

????try {

????????//創(chuàng)建一個(gè)指定Bean實(shí)例對(duì)象,如果有父級(jí)繼承,則合并子//類和父類的定義

????????return createBean(beanName, mbd, args);

????}catch (BeansException ex) {

? ? ?????//顯式地從容器單態(tài)模式Bean緩存中清除實(shí)例對(duì)象

????????destroySingleton(beanName);

????????throw ex;

????}

}

});

????//獲取給定Bean的實(shí)例對(duì)象

????bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

}

????//IoC容器創(chuàng)建原型模式Bean實(shí)例對(duì)象

else if (mbd.isPrototype()) {

????//原型模式(Prototype)是每次都會(huì)創(chuàng)建一個(gè)新的對(duì)象

????Object prototypeInstance = null;

try {

????//回調(diào)beforePrototypeCreation方法,默認(rèn)的功能是注冊(cè)當(dāng)前創(chuàng)//建的原型對(duì)象

????beforePrototypeCreation(beanName);

????//創(chuàng)建指定Bean對(duì)象實(shí)例

????prototypeInstance = createBean(beanName, mbd, args);

}finally {

????????//回調(diào)afterPrototypeCreation方法,默認(rèn)的功能告訴IoC容器指//定Bean的原型對(duì)象不再創(chuàng)建了

????????afterPrototypeCreation(beanName);

}

????????//獲取給定Bean的實(shí)例對(duì)象

????????bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

}

????//要?jiǎng)?chuàng)建的Bean既不是單態(tài)模式,也不是原型模式,則根據(jù)Bean定義資源中

????//配置的生命周期范圍,選擇實(shí)例化Bean的合適方法,這種在Web應(yīng)用程序中

????//比較常用,如:request、session、application等生命周期

else {

????String scopeName = mbd.getScope();

????final Scope scope = this.scopes.get(scopeName);

????//Bean定義資源中沒(méi)有配置生命周期范圍,則Bean定義不合法

????if (scope == null) {

????????throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");

????}

try {

//這里又使用了一個(gè)匿名內(nèi)部類,獲取一個(gè)指定生命周期范圍的實(shí)例

Object scopedInstance = scope.get(beanName, new ObjectFactory() {

public Object getObject() throws BeansException {

beforePrototypeCreation(beanName);

try {

return createBean(beanName, mbd, args);

}

finally {

afterPrototypeCreation(beanName);

}

}

});

//獲取給定Bean的實(shí)例對(duì)象

????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);

}

}

}

//對(duì)創(chuàng)建的Bean實(shí)例對(duì)象進(jìn)行類型檢查

if (requiredType != null && bean != null &&?

!requiredType.isAssignableFrom(bean.getClass())) {

????throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());

}

????return (T) bean;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容