通過(guò)之前對(duì)spring ioc的剖析值漫,我們了解到:Spring IOC容器對(duì)Bean定義資源的定位澳腹、讀入和解析y以及初始化和依賴(lài)注入過(guò)程,這些均屬于容器的基本功能特性杨何,接下來(lái)就容器的一些高級(jí)特性我們進(jìn)行相應(yīng)的學(xué)習(xí)酱塔。
1. 配置lazy-init屬性實(shí)現(xiàn)預(yù)實(shí)例化
我們已經(jīng)知道IOC容器的初始化過(guò)程就是對(duì)bean定義資源的定位、載入和注冊(cè)危虱,此時(shí)容器對(duì)bean的依賴(lài)注入并沒(méi)有發(fā)生羊娃,此時(shí):
bean的依賴(lài)注入:
- 發(fā)生時(shí)間:在應(yīng)用程序第一次向容器索取bean時(shí)。
- 方式:通過(guò)getBean方法的調(diào)用完成埃跷。
但是如果當(dāng)bean定義資源的<Bean>元素中配置了lazy-init屬性后蕊玷,容器將會(huì)在初始化時(shí)對(duì)所配置的bean進(jìn)行預(yù)實(shí)例化,此時(shí):
bean的依賴(lài)注入:
- 發(fā)生時(shí)間:容器初始化時(shí)已經(jīng)完成。
- 方式:容器初始化捌蚊。
- 當(dāng)應(yīng)用程序第一次向容器索取被管理的bean時(shí)集畅,直接從容器中獲取已經(jīng)完成依賴(lài)注入的bean,提高了應(yīng)用第一次向容器獲取bean的性能缅糟。
接下來(lái)挺智,通過(guò)剖析源碼分析其實(shí)現(xiàn)過(guò)程:
首先從AbstractApplicationContext類(lèi)的refresh方法開(kāi)始:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//調(diào)用容器準(zhǔn)備刷新的方法
prepareRefresh();
/**調(diào)用子類(lèi)中refreshBeanFactory()方法
*啟動(dòng)Bean定義資源文件的過(guò)程
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//為BeanFactory配置容器特性
prepareBeanFactory(beanFactory);
try {
//為容器的子類(lèi)指定事件處理器
postProcessBeanFactory(beanFactory);
//調(diào)用所有注冊(cè)的BeanFactoryPostProcessor的Bean
invokeBeanFactoryPostProcessors(beanFactory);
/**為BeanFactory注冊(cè)BeanPost事件處理器.
*BeanPostProcessor是Bean后置處理器,用于監(jiān)聽(tīng)容器觸發(fā)的事件
*/
registerBeanPostProcessors(beanFactory);
//初始化信息源
initMessageSource();
//初始化容器事件傳播器.
initApplicationEventMulticaster();
//調(diào)用子類(lèi)Bean初始化方法
onRefresh();
//為事件傳播器注冊(cè)事件監(jiān)聽(tīng)器.
registerListeners();
//對(duì)容器lazy-init屬性處理的入口方法
finishBeanFactoryInitialization(beanFactory);
/**初始化容器的生命周期事件處理器
*并發(fā)布容器的生命周期事件
*/
finishRefresh();
}
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
其中:
//對(duì)容器lazy-init屬性處理的入口方法
finishBeanFactoryInitialization(beanFactory);
此方法位于類(lèi)AbstractApplicationContext中窗宦,是對(duì)配置了預(yù)實(shí)例化屬性的bean進(jìn)行預(yù)初始化過(guò)程赦颇,源碼如下:
//對(duì)配置了lazy-init屬性的bean進(jìn)行預(yù)實(shí)例化處理
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
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));
}
beanFactory.setTempClassLoader(null);
//對(duì)容器中所有注冊(cè)的BeanDefinition緩存二鳄,防止在預(yù)實(shí)例化過(guò)程中被修改
beanFactory.freezeConfiguration();
//對(duì)配置了lazy-init屬性的單例模式下的bean進(jìn)行預(yù)實(shí)例化處理
beanFactory.preInstantiateSingletons();
}
方法preInstantiateSingletons對(duì)配置lazy-init屬性單例bean的預(yù)實(shí)例化:
//對(duì)配置lazy-init屬性單例bean的預(yù)實(shí)例化
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
/**在對(duì)配置lazy-init屬性單例bean的預(yù)實(shí)例化過(guò)程中,
*須保證多線(xiàn)程同步媒怯,以確保數(shù)據(jù)的一致性
*/
synchronized (this.beanDefinitionMap) {
for (String beanName : this.beanDefinitionNames) {
//獲取指定名稱(chēng)的bean定義
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
/*如果bean不是抽象的订讼,同時(shí)是單例模式的bean,
*并且lazy-init屬性配置為false
*/
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果指定名稱(chēng)的bean是創(chuàng)建容器的bean
if (isFactoryBean(beanName)) {
final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
//標(biāo)識(shí)是否需要預(yù)實(shí)例化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return ((SmartFactoryBean) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
/*如果指定名稱(chēng)的bean不是創(chuàng)建容器的bean
*調(diào)用getBean方法扇苞,觸發(fā)容器對(duì)bean實(shí)例化和依賴(lài)注入過(guò)程
*/
getBean(beanName);
}
}
}
}
}
經(jīng)過(guò)上述分析:
如果設(shè)置了lazy-init屬性欺殿,則容器在完成bean定義的注冊(cè)之后,會(huì)通過(guò)getBean方法鳖敷,觸發(fā)對(duì)指定Bean的初始化和依賴(lài)注入過(guò)程脖苏。
當(dāng)應(yīng)用第一次向容器索取所需的bean時(shí),容器不再需要對(duì)bean進(jìn)行初始化和依賴(lài)注入定踱,直接從已經(jīng)完成實(shí)例化和依賴(lài)注入的bean中取一個(gè)線(xiàn)程的bean棍潘,提高了第一次獲取bean的性能。
2. FactoryBean的實(shí)現(xiàn)
FactoryBean:
- 概念:工廠(chǎng)bean崖媚,本質(zhì)也是bean亦歉。
- 作用:產(chǎn)生其他bean實(shí)例提供一個(gè)工廠(chǎng)方法,該方法用來(lái)返回其他bean實(shí)例畅哑。
源碼如下:
//用于產(chǎn)生其他對(duì)象
public interface FactoryBean<T> {
//獲取容器管理的對(duì)象實(shí)例
T getObject() throws Exception;
//獲取Bean工廠(chǎng)創(chuàng)建的對(duì)象的類(lèi)型
Class<?> getObjectType();
/*判斷bean工廠(chǎng)創(chuàng)建的對(duì)象是否是單態(tài)模式肴楷,
*如果是單例模式,則整個(gè)容器中只有一個(gè)實(shí)例對(duì)象敢课,
*每次請(qǐng)求都返回同一個(gè)實(shí)例對(duì)象
*/
boolean isSingleton();
}
類(lèi)AbstractBeanFactory的doGetBean方法中使用FactoryBean:
//真正實(shí)現(xiàn)向IOC容器獲取bean的方法阶祭,也是觸發(fā)依賴(lài)注入功能的地方
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
/**根據(jù)指定名稱(chēng)獲取被管理bean名稱(chēng),首先剝離指定名稱(chēng)中對(duì)容器的相關(guān)依賴(lài)
*如果指定的是別名直秆,需要將別名轉(zhuǎn)換為規(guī)范的bean名稱(chēng)
*/
final String beanName = transformedBeanName(name);
Object bean;
/**先從緩存中取是否已經(jīng)有被創(chuàng)建過(guò)的單例類(lèi)型的bean濒募,
*對(duì)于單例模式的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()) {
/**如果指定名稱(chēng)的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ì)象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
.........................
}
方法getObjectForBeanInstance完成FactoryBean的相關(guān)處理:
//獲取給定bean的實(shí)例對(duì)象瑰剃,主要是完成FactoryBean的相關(guān)處理
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
/**容器得到了bean實(shí)例對(duì)象,這個(gè)實(shí)例對(duì)象可能是一個(gè)普通的bean筝野,也可能是一個(gè)工廠(chǎng)bean晌姚,
*如果是一個(gè)工廠(chǎng)bean,則使用它創(chuàng)建一個(gè)bean實(shí)例對(duì)象歇竟,
*如果調(diào)用本身就想獲得一個(gè)容器的引用挥唠,則指定返回這個(gè)工廠(chǎng)bean實(shí)例對(duì)象
*/
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
/**如果bean實(shí)例不是工廠(chǎng)bean,或者指定名稱(chēng)是容器的解引用焕议,
*調(diào)用者向獲取對(duì)容器的引用宝磨,則直接返回當(dāng)前的bean實(shí)例
*/
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
/**如果處理指定名稱(chēng)不是容器的解引用,或者根據(jù)名稱(chēng)獲取的bean實(shí)例對(duì)象是一個(gè)工廠(chǎng)Bean
*那么使用工廠(chǎng)Bean創(chuàng)建一個(gè)bean的實(shí)例對(duì)象
*/
Object object = null;
if (mbd == null) {
//從Bean工廠(chǎng)緩存中獲取給定名稱(chēng)的bean實(shí)例對(duì)象
object = getCachedObjectForFactoryBean(beanName);
}
/**如果對(duì)象為null,
*讓Bean工廠(chǎng)生產(chǎn)給定名稱(chēng)的bean對(duì)象實(shí)例
*/
if (object == null) {
FactoryBean factory = (FactoryBean) beanInstance;
//如果從Bean工廠(chǎng)生產(chǎn)的bean是單例模式唤锉,則進(jìn)行緩存
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
/**如果從容器得到bean定義信息世囊,并且bean定義信息不是虛構(gòu)的,
*則讓工廠(chǎng)Bean生產(chǎn)bean實(shí)例對(duì)象
*/
boolean synthetic = (mbd != null && mbd.isSynthetic());
//調(diào)用方法getObjectFromFactoryBean實(shí)現(xiàn)工廠(chǎng)Bean生產(chǎn)bean對(duì)象實(shí)例的過(guò)程
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
注:
解引用:指所引用對(duì)象的本身數(shù)據(jù)窿祥。
類(lèi)AbstractBeanFactory中方法getObjectFromFactoryBean實(shí)現(xiàn)工廠(chǎng)Bean生產(chǎn)bean對(duì)象實(shí)例的過(guò)程:
//Bean工廠(chǎng)生產(chǎn)bean實(shí)例對(duì)象
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
//如果工廠(chǎng)Bean是單態(tài)模式株憾,并且工廠(chǎng)Bean緩存中存在指定名稱(chēng)的bean實(shí)例對(duì)象
if (factory.isSingleton() && containsSingleton(beanName)) {
//須多線(xiàn)程同步,防止數(shù)據(jù)不一致
synchronized (getSingletonMutex()) {
//先從工廠(chǎng)Bean緩存中獲取指定名稱(chēng)的bean實(shí)例對(duì)象
Object object = this.factoryBeanObjectCache.get(beanName);
/**如果工廠(chǎng)Bean緩存中沒(méi)有指定名稱(chēng)的實(shí)例對(duì)象晒衩,
* 則生產(chǎn)該實(shí)例對(duì)象
*/
if (object == null) {
//調(diào)用工廠(chǎng)Bean的getObject方法生產(chǎn)指定bean的實(shí)例對(duì)象
object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
//將生產(chǎn)的實(shí)例對(duì)象添加到工廠(chǎng)Bean緩存中
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
return (object != NULL_OBJECT ? object : null);
}
}
//調(diào)用工廠(chǎng)Bean的getObject方法生產(chǎn)指定bean的實(shí)例對(duì)象
else {
return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
}
}
方法doGetObjectFromFactoryBean調(diào)用方法getObject生產(chǎn)指定bean的實(shí)例對(duì)象:
//調(diào)用工廠(chǎng)Bean的getObject方法生產(chǎn)指定bean的實(shí)例對(duì)象
private Object doGetObjectFromFactoryBean(
final FactoryBean factory, final String beanName, final boolean shouldPostProcess)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
//BeanFactory接口實(shí)現(xiàn)類(lèi)創(chuàng)建對(duì)象
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//調(diào)用BeanFactory接口實(shí)現(xiàn)類(lèi)的創(chuàng)建對(duì)象方法
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);
}
//如果創(chuàng)建出來(lái)的實(shí)例對(duì)象為null嗤瞎,或由于單例對(duì)象正在創(chuàng)建而返回null
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
//為已創(chuàng)建的bean實(shí)例對(duì)象添加BeanPostProcessor后置處理器
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex);
}
}
return object;
}
3. BeanPostProcessor后置處理器的實(shí)現(xiàn)
BeanPostProcessor后置處理器
- 名稱(chēng):是一個(gè)監(jiān)聽(tīng)器。
- 作用:監(jiān)聽(tīng)容器觸發(fā)的Bean聲明周期事件浸遗。
- 影響:后置處理器向容器注冊(cè)以后猫胁,容器中管理的bean就具備了接收IOC容器事件回調(diào)的能力箱亿。
- 使用方式:需要提供一個(gè)實(shí)現(xiàn)接口BeanPostProcessor的實(shí)現(xiàn)類(lèi)跛锌,然后在Bean的配置文件中設(shè)置即可。
BeanPostProcessor的源碼如下:
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
public interface BeanPostProcessor {
//為在bean的初始化前提供回調(diào)入口
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//為在bean的初始化之后提供回調(diào)入口
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
真正實(shí)現(xiàn)創(chuàng)建bean對(duì)象并進(jìn)行依賴(lài)注入的方法是AbstractAutowireCapableBeanFactory類(lèi)的doCreateBean方法:
//真正創(chuàng)建bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
//創(chuàng)建bean實(shí)例對(duì)象
……
try {
//將bean實(shí)例對(duì)象封裝届惋,并且bean定義中配置的屬性值賦值給實(shí)例對(duì)象
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//初始化bean對(duì)象
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);
}
}
……
//為應(yīng)用返回所需要的實(shí)例對(duì)象
return exposedObject;
}
由上述可知髓帽,為bean實(shí)例對(duì)象添加BeanPostProcessor后置處理器的入口的是initializeBean方法:
//初始容器創(chuàng)建的bean實(shí)例對(duì)象,為其添加BeanPostProcessor后置處理器
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//為bean實(shí)例對(duì)象包裝相關(guān)屬性
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//回調(diào)方法的調(diào)用脑豹,為Bean實(shí)例初始化前做一些處理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
/**調(diào)用Bean實(shí)例對(duì)象初始化的方法郑藏,在Spring Bean定義配置,
*文件中通過(guò)init-method屬性指定的
*/
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
/**對(duì)BeanPostProcessor后置處理器的postProcessAfterInitialization
*回調(diào)方法的調(diào)用瘩欺,為Bean實(shí)例初始化之后做一些處理
*/
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
其中必盖,方法applyBeanPostProcessorsBeforeInitialization處理實(shí)例對(duì)象初始化之前
//調(diào)用BeanPostProcessor后置處理器實(shí)例對(duì)象初始化之前的處理方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍歷容器為所創(chuàng)建的bean添加的所有BeanPostProcessor后置處理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
/**調(diào)用Bean實(shí)例所有的后置處理中的初始化前處理方法,
*為Bean實(shí)例對(duì)象在初始化之前做一些自定義的處理操作
*/
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
其中俱饿,方法applyBeanPostProcessorsAfterInitialization處理實(shí)例對(duì)象初始化之后
//調(diào)用BeanPostProcessor后置處理器實(shí)例對(duì)象初始化之后的處理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍歷容器為所創(chuàng)建的Bean添加的所有BeanPostProcessor后置處理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
/**調(diào)用Bean實(shí)例所有的后置處理中的初始化后處理方法歌粥,
*為Bean實(shí)例對(duì)象在初始化之后做一些自定義的處理操作
*/
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
AdvisorAdapterRegistrationManager在Bean對(duì)象初始化后注冊(cè)通知適配器:
//為容器中管理的bean注冊(cè)面向切面編程的通知適配器
public class AdvisorAdapterRegistrationManager implements BeanPostProcessor {
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
this.advisorAdapterRegistry = advisorAdapterRegistry;
}
//BeanPostProcessor在bean對(duì)象初始化前的操作
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//直接返回容器創(chuàng)建的Bean對(duì)象
return bean;
}
//BeanPostProcessor在bean對(duì)象初始化后的操作
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AdvisorAdapter){
/**如果容器創(chuàng)建的bean實(shí)例對(duì)象是一個(gè)切面通知適配器体捏,
*則向容器的注冊(cè)
*/
this.advisorAdapterRegistry.registerAdvisorAdapter((AdvisorAdapter) bean);
}
return bean;
}
}
未完跟進(jìn)中......(autowiring實(shí)現(xiàn)原理)
4. Spring IOC容器之a(chǎn)utowiring實(shí)現(xiàn)原理
容器提供兩種方式用來(lái)管理bean依賴(lài)關(guān)系:
- 顯式管理:通過(guò)BeanDefinition的屬性值和構(gòu)造方法實(shí)現(xiàn)脚祟。
- autowiring:自動(dòng)裝配功能,不需對(duì)bean屬性的依賴(lài)關(guān)系做顯式聲明驶俊,只需配置autowiring屬性枣购,容器將通過(guò)反射自動(dòng)查找屬性的類(lèi)型和名稱(chēng)嬉探,之后基于屬性的類(lèi)型或名稱(chēng)自動(dòng)匹配容器中的bean,自動(dòng)完成依賴(lài)注入棉圈。
autowiring自動(dòng)裝配特性: 容器對(duì)Bean的自動(dòng)裝配發(fā)生在容器對(duì)Bean依賴(lài)注入的過(guò)程中涩堤。
而容器對(duì)bean實(shí)例對(duì)象的屬性注入的處理發(fā)生在類(lèi)AbstractAutoWireCapableBeanFactory中的方法populateBean中:
(1) 屬性依賴(lài)注入
類(lèi)AbstractAutoWireCapableBeanFactory的方法populateBean實(shí)現(xiàn)bean屬性依賴(lài)注入的功能:
protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {
//獲取bean定義的屬性值
PropertyValues pvs = mbd.getPropertyValues();
…
/**對(duì)依賴(lài)注入處理,
*首先處理autowiring自動(dòng)裝配的依賴(lài)注入
*/
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根據(jù)bean名稱(chēng)進(jìn)行autowiring自動(dòng)裝配處理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根據(jù)bean類(lèi)型進(jìn)行autowiring自動(dòng)裝配處理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
}
//處理非autowiring的屬性依賴(lài)注入
……
}
(2) 根據(jù)bean名稱(chēng)或類(lèi)型進(jìn)行autowiring自動(dòng)依賴(lài)注入:
根據(jù)名稱(chēng)對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入:
//根據(jù)名稱(chēng)對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//處理 bean對(duì)象中非簡(jiǎn)單屬性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
/**如果容器中包含指定名稱(chēng)的bean
*調(diào)用getBean方法向容器索取指定名稱(chēng)的bean實(shí)例分瘾,
*迭代觸發(fā)對(duì)屬性的初始化和依賴(lài)注入
*/
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
//指定名稱(chēng)屬性注冊(cè)依賴(lài)bean名稱(chēng)胎围,屬性依賴(lài)注入
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");
}
}
}
}
根據(jù)類(lèi)型對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入:
//根據(jù)類(lèi)型對(duì)屬性進(jìn)行自動(dòng)依賴(lài)注入
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//獲取用戶(hù)定義的類(lèi)型轉(zhuǎn)換器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//存放解析的要注入的屬性
Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
//處理bean對(duì)象中非簡(jiǎn)單屬性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
//獲取指定屬性名稱(chēng)的屬性描述器
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
//不對(duì)Object類(lèi)型的屬性進(jìn)行autowiring自動(dòng)依賴(lài)注入
if (!Object.class.equals(pd.getPropertyType())) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
//創(chuàng)建一個(gè)要被注入的依賴(lài)描述
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
/**根據(jù)容器的bean定義解析依賴(lài)關(guān)系,
*返回所有要被注入的Bean對(duì)象
*/
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
//為屬性賦值所引用的對(duì)象
pvs.add(propertyName, autowiredArgument);
}
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 + "'");
}
}
//釋放已自動(dòng)注入的屬性
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
真正實(shí)現(xiàn)屬性注入的是類(lèi)DefaultSingletonBeanRegistry的方法registerDependentBean:
//為指定的bean注入依賴(lài)的bean
public void registerDependentBean(String beanName, String dependentBeanName) {
//處理bean名稱(chēng)
String canonicalName = canonicalName(beanName);
/**多線(xiàn)程同步,保證容器內(nèi)數(shù)據(jù)的一致性
*根據(jù)bean名稱(chēng)痊远,
*在全部依賴(lài)bean名稱(chēng)集合找查找給定名稱(chēng)bean的依賴(lài)bean
*/
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
//將bean所依賴(lài)的bean添加到容器的集合中
dependentBeans.add(dependentBeanName);
}
/**指定名稱(chēng)bean的依賴(lài)bean集合找查找給定名稱(chēng)
*bean的依賴(lài)bean
*/
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<String>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
//將Bean所依賴(lài)的Bean添加到容器的集合中
dependenciesForBean.add(canonicalName);
}
}
autowiring的實(shí)現(xiàn)過(guò)程:
- 通過(guò)對(duì)bean的屬性迭代調(diào)用getBean方法垮抗,完成依賴(lài)bean的初始化和依賴(lài)注入。
- 將依賴(lài)bean的屬性引用設(shè)置到被依賴(lài)的bean屬性上碧聪。
- 將依賴(lài)bean的名稱(chēng)和被依賴(lài)bean的名稱(chēng)存儲(chǔ)在容器集合中冒版。
autowiring屬性自動(dòng)依賴(lài)注入是一個(gè)很方便的特性,可簡(jiǎn)化開(kāi)發(fā)時(shí)的配置逞姿,但自動(dòng)屬性依賴(lài)注入也有不足辞嗡。
autowiring屬性自動(dòng)依賴(lài)注入的不足:
- bean的依賴(lài)關(guān)系在配置文件中并不具有易讀性,不利于維護(hù)造成一定困難滞造。
- 將依賴(lài)注入交給容器自動(dòng)執(zhí)行续室,若配置不當(dāng),后果無(wú)法評(píng)估谒养。