本文開始久脯,將利用《spring源碼閱讀1——環(huán)境搭建&閱讀方法》中提到的方法逐步對(duì)spring源碼進(jìn)行解讀霞怀。
本文主要對(duì)DefaultListtableBeanFactory的父級(jí)接口進(jìn)行剖析、解讀距帅,旨在探究明白spring是如何
對(duì)組件(bean)進(jìn)行管理的抖仅。
本文使用的spring版本:4.1.1.RELEASE
順藤摸瓜——DefaultListableBeanFactory
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
HelloService helloService = context.getBean(HelloService.class);
System.out.println(helloService.sayHello());
}
還是從這個(gè)main函數(shù)入手,容器的getBean(Class<T> requiredType)方法咏窿,是通過類對(duì)象來獲取實(shí)例對(duì)象斟或,通過調(diào)試可以知道,該方法的具體實(shí)現(xiàn)在
AbstractApplicationContext.java
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
查看getBeanFactory()方法
AbstractRefreshableApplicationContext.java
/** Bean factory for this context */
private DefaultListableBeanFactory beanFactory;
...
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
通過debug過程中集嵌,可以看到這個(gè)beanFactory的類型是DefaultListableBeanFactory萝挤。
繼續(xù)調(diào)試,進(jìn)入getBean方法根欧,可以看到這個(gè)方法的具體實(shí)現(xiàn)確實(shí)在類DefaultListableBeanFactory中
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
@Override
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
String[] beanNames = getBeanNamesForType(requiredType);
if (beanNames.length > 1) {
ArrayList<String> autowireCandidates = new ArrayList<String>();
for (String beanName : beanNames) {
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (autowireCandidates.size() > 0) {
beanNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
}
}
...
}
至此怜珍,我感覺已經(jīng)找到了所謂的“瓜”,就是DefaultListableBeanFactory這個(gè)類凤粗,暫且不糾結(jié)這個(gè)beanFactory是如何實(shí)例化的酥泛,這不是本文的重點(diǎn)。
化整為零
這一節(jié)嫌拣,我們將整理出DefaultListableBeanFactory這個(gè)類的層次結(jié)構(gòu)柔袁,逐步了解各個(gè)關(guān)聯(lián)的類的作用。
子類
通過工具异逐,查看DefaultListableBeanFactory有哪些子類
可以看到DefaultListableBeanFactory只有一個(gè)子類XmlBeanFactory捶索。回顧spring中bean的幾種裝配方式灰瞻,在對(duì)照該類的注釋腥例,可知這個(gè)類就是使用xml文件來裝配bean組件的。后面的章節(jié)會(huì)詳細(xì)介紹這個(gè)類酝润,這里不做贅述院崇。
父級(jí)層次結(jié)構(gòu)
同樣的,用工具查看DefaultListableBeanFactory的層級(jí)結(jié)構(gòu)以及類圖
小技巧:
Ctrl + H 展示當(dāng)前類的層級(jí)結(jié)構(gòu)圖:左上角可選父類袍祖、子類以及全部展示視圖
Ctrl + Alt + Shift + U 展示當(dāng)前類的類圖底瓣,可過濾展示內(nèi)容
通過這個(gè)圖可以知道DefaultListableBeanFactory繼承了AbstractAutowireCapableBeanFactory類,并且實(shí)現(xiàn)了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口蕉陋,已經(jīng)可以清晰地從全局角度了解DefaultListableBeanFactory的脈絡(luò)捐凭。
各個(gè)擊破——接口
小技巧:
Ctrl + F12 查看當(dāng)前類的所有方法和屬性
AliasRegistry
在對(duì)bean進(jìn)行定義時(shí),除了使用id屬性來指定名稱之外凳鬓,為了提供多個(gè)名稱茁肠,可以使用alias標(biāo)簽來指定。該接口定義了對(duì)alias的注冊(cè)管理功能缩举。
getAliases() : 獲取alias標(biāo)簽數(shù)組
isAlias() : 判斷標(biāo)簽是否存在
registerAlias() : 注冊(cè)alias標(biāo)簽
removeAlias() : 移除已注冊(cè)的alias標(biāo)簽
BeanDefinitionRegistry
提供bean的配置清單注冊(cè)管理功能垦梆。
方法說明:
registerBeanDefinition() : 注冊(cè)BeanDefinition
removeBeanDefinition() : 移除BeanDefinition
isBeanNameInUse() : 重名校驗(yàn)
containsBeanDefinition() : 工廠中是否存在BeanDefinition
getBeanDefinitionCount() : 返回工廠中BeanDefinition的總數(shù)
getBeanDefinitionNames() : 返回工廠中BeanDefinition的名稱
bean的配置清單(BeanDefinition)是什么匹颤?
回憶下spring中,根據(jù)xml文檔來裝配bean托猩,舉個(gè)栗子:
<bean id="123" class="com.spring.student">
<property name="name" value="XiaoMing" />
<property name="age" value="17" />
<property name="sex" value="man" />
</bean>
這是一個(gè)student實(shí)例的配置文件印蓖,里面記錄著id為123的student實(shí)例的姓名、年齡和
性別三個(gè)屬性京腥,spring讀取以后就保存為BeanDefinition赦肃,容器可以根據(jù)這個(gè)信息進(jìn)行
實(shí)例化。這就是配置清單~
BeanFactory
查看BeanFactory接口中定義的方法:
BeanFactory接口公浪,定義了一個(gè)基本的bean管理工廠他宛。
方法說明:
containsBean() : 工廠中是否存在bean實(shí)例
getAliases() : 獲取實(shí)例bean的別名數(shù)組
getBean() : 獲取bean實(shí)例(多個(gè)重載方法)
getType() ; 獲取bean實(shí)例類型
isPrototype() : bean實(shí)例是否為prototype
isSingleton() : bean實(shí)例是否為單例
isTypeMatch() : bean實(shí)例類型是否和給定值匹配
ListableBeanFactory
這個(gè)接口是對(duì)BeanFactory的擴(kuò)展,提供了根據(jù)條件獲取bean的配置清單(BeanDefinition欠气,暫且就這么稱呼吧)厅各。
方法說明:
containsBeanDefinition() : 工廠中是否存在BeanDefinition
getBeanDefinitionCount() : 返回工廠中BeanDefinition的總數(shù)
getBeanDefinitionNames() : 返回工廠中BeanDefinition的名稱
getBeanNamesForType() : 根據(jù)類型獲取BeanDefinition的名稱
getBeansOfType() : 根據(jù)類型獲取Bean
getBeanNamesForAnnotation() : 根據(jù)注解獲取Bean名稱
getBeansWithAnnotation() : 根據(jù)注解獲取Bean
findAnnotationOnBean() : 獲取BeanDefinition的注解
HierarchicalBeanFactory
同樣是繼承于BeanFactory,這個(gè)接口主要和層級(jí)關(guān)系相關(guān)预柒,包含兩個(gè)方法:
方法說明:
getParentBeanFactory() : 獲取父級(jí)BeanFactory
containsLocalBean() : 返回當(dāng)前BeanFactory是否存在bean
如果對(duì)方法的作用有所疑問队塘,也沒有關(guān)系,到后面碰到對(duì)其實(shí)現(xiàn)和使用卫旱,便會(huì)豁然開朗。
AutowireCapableBeanFactory
這個(gè)接口為BeanFactory定義了支持依賴注入功能围段,主要包含:
方法說明:
createBean() : 創(chuàng)建bean實(shí)例
autowireBean() : 注入bean實(shí)例
configureBean() : 配置bean實(shí)例顾翼,注入bean屬性,執(zhí)行回調(diào)函數(shù)等
resolveDependency() : 解決bean實(shí)例的依賴
autowireBeanProperties() : 注入bean實(shí)例的屬性
applyBeanPropertyValues() : 注入bean實(shí)例的屬性值
initializeBean() : 初始化bean實(shí)例
applyBeanPostProcessorsBeforeInitialization() : 應(yīng)用bean的前置處理
applyBeanPostProcessorsAfterInitialization() : 應(yīng)用bean的后置處理
destroyBean() : 銷毀bean實(shí)例
SigletonBeanRegistry
這個(gè)接口定義了容器對(duì)單例的注冊(cè)管理方法奈泪。
方法說明:
registerSingleton() : 注冊(cè)bean
getSingleton() : 獲取bean
containsSingleton() : 返回是否包含bean
getSingletonNames() : 獲取bean實(shí)例(單例)的名稱數(shù)組
getSingletonCount() : 獲取容器中bean實(shí)例的總數(shù)
ConfigurableBeanFactory
這個(gè)接口繼承了SingletonBeanRegistry和HierarchicalBeanFactory兩個(gè)接口适贸,增加了beanFactory的配置功能。主要是許多屬性的get和set方法涝桅。由于配置項(xiàng)較多拜姿,較為復(fù)雜,這里先不詳細(xì)介紹
ConfigurableListableBeanFactory
新增了忽略類型以及接口
總結(jié)
至此冯遂,已經(jīng)了解完所有的相關(guān)接口蕊肥,整理下所有的接口中定義的概念:
- Bean : 組件對(duì)象,sping容器所管理的對(duì)象
- SingletonBean : 特殊的bean蛤肌,其在容器中僅有一個(gè)實(shí)例
- BeanDefinition : bean的配置清單壁却,或者說定義文件,spring可以根據(jù)該文件實(shí)例化出對(duì)象
- Alias : bean的別名裸准,一個(gè)bean可以有多個(gè)名稱
- BeanFactory : bean工廠展东,為其他組件提供管理容器
通過這個(gè)類圖,感覺整個(gè)BeanFactory生態(tài)圈已經(jīng)構(gòu)建起來了炒俱。不得不感嘆面向?qū)ο蟮镊攘ρ嗡啵瑑H僅是定義了接口爪膊,便展示了一個(gè)完整的功能模塊。
本文到這就要結(jié)束了砸王,回顧下
1推盛、首先是通過調(diào)試的方法,找到了整個(gè)bean管理功能模塊的核心DefaultListableBeanFactory
2处硬、然后是對(duì)DefaultListableBeanFactory所實(shí)現(xiàn)的各個(gè)父級(jí)接口進(jìn)行源碼閱讀和分析
3小槐、最后再通過系統(tǒng)的整理出該功能模塊的概覽
通過以上三步,完成了BeanFactory的整個(gè)功能定義的概覽荷辕,下次會(huì)給大家?guī)淼氖侨绾我徊揭徊降?實(shí)現(xiàn)上述的定義
本文到此就結(jié)束凿跳,希望能夠幫到大家。
純屬原創(chuàng)疮方,轉(zhuǎn)載請(qǐng)聲明出處控嗜。
——作者:陳來件(QQ:810522442)