本文開始,將利用《spring源碼閱讀1——環(huán)境搭建&閱讀方法》中提到的方法逐步對spring源碼進行解讀。
本文主要對DefaultListtableBeanFactory的父級接口進行剖析、解讀,旨在探究明白spring是如何
對組件(bean)進行管理的。
本文使用的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());
}
還是從這個main函數(shù)入手,容器的getBean(Class<T> requiredType)方法,是通過類對象來獲取實例對象,通過調試可以知道,該方法的具體實現(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過程中,可以看到這個beanFactory的類型是DefaultListableBeanFactory。

繼續(xù)調試,進入getBean方法,可以看到這個方法的具體實現(xiàn)確實在類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()]);
}
}
...
}
至此,我感覺已經找到了所謂的“瓜”,就是DefaultListableBeanFactory這個類,暫且不糾結這個beanFactory是如何實例化的,這不是本文的重點。
化整為零
這一節(jié),我們將整理出DefaultListableBeanFactory這個類的層次結構,逐步了解各個關聯(lián)的類的作用。
子類
通過工具,查看DefaultListableBeanFactory有哪些子類

可以看到DefaultListableBeanFactory只有一個子類XmlBeanFactory。回顧spring中bean的幾種裝配方式,在對照該類的注釋,可知這個類就是使用xml文件來裝配bean組件的。后面的章節(jié)會詳細介紹這個類,這里不做贅述。
父級層次結構
同樣的,用工具查看DefaultListableBeanFactory的層級結構以及類圖
小技巧:
Ctrl + H 展示當前類的層級結構圖:左上角可選父類、子類以及全部展示視圖
Ctrl + Alt + Shift + U 展示當前類的類圖,可過濾展示內容


通過這個圖可以知道DefaultListableBeanFactory繼承了AbstractAutowireCapableBeanFactory類,并且實現(xiàn)了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,已經可以清晰地從全局角度了解DefaultListableBeanFactory的脈絡。
各個擊破——接口
小技巧:
Ctrl + F12 查看當前類的所有方法和屬性
AliasRegistry

在對bean進行定義時,除了使用id屬性來指定名稱之外,為了提供多個名稱,可以使用alias標簽來指定。該接口定義了對alias的注冊管理功能。
getAliases() : 獲取alias標簽數(shù)組
isAlias() : 判斷標簽是否存在
registerAlias() : 注冊alias標簽
removeAlias() : 移除已注冊的alias標簽
BeanDefinitionRegistry

提供bean的配置清單注冊管理功能。
方法說明:
registerBeanDefinition() : 注冊BeanDefinition
removeBeanDefinition() : 移除BeanDefinition
isBeanNameInUse() : 重名校驗
containsBeanDefinition() : 工廠中是否存在BeanDefinition
getBeanDefinitionCount() : 返回工廠中BeanDefinition的總數(shù)
getBeanDefinitionNames() : 返回工廠中BeanDefinition的名稱
bean的配置清單(BeanDefinition)是什么?
回憶下spring中,根據(jù)xml文檔來裝配bean,舉個栗子:
<bean id="123" class="com.spring.student">
<property name="name" value="XiaoMing" />
<property name="age" value="17" />
<property name="sex" value="man" />
</bean>
這是一個student實例的配置文件,里面記錄著id為123的student實例的姓名、年齡和
性別三個屬性,spring讀取以后就保存為BeanDefinition,容器可以根據(jù)這個信息進行
實例化。這就是配置清單~
BeanFactory
查看BeanFactory接口中定義的方法:

BeanFactory接口,定義了一個基本的bean管理工廠。
方法說明:
containsBean() : 工廠中是否存在bean實例
getAliases() : 獲取實例bean的別名數(shù)組
getBean() : 獲取bean實例(多個重載方法)
getType() ; 獲取bean實例類型
isPrototype() : bean實例是否為prototype
isSingleton() : bean實例是否為單例
isTypeMatch() : bean實例類型是否和給定值匹配
ListableBeanFactory

這個接口是對BeanFactory的擴展,提供了根據(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,這個接口主要和層級關系相關,包含兩個方法:
方法說明:
getParentBeanFactory() : 獲取父級BeanFactory
containsLocalBean() : 返回當前BeanFactory是否存在bean
如果對方法的作用有所疑問,也沒有關系,到后面碰到對其實現(xiàn)和使用,便會豁然開朗。
AutowireCapableBeanFactory

這個接口為BeanFactory定義了支持依賴注入功能,主要包含:
方法說明:
createBean() : 創(chuàng)建bean實例
autowireBean() : 注入bean實例
configureBean() : 配置bean實例,注入bean屬性,執(zhí)行回調函數(shù)等
resolveDependency() : 解決bean實例的依賴
autowireBeanProperties() : 注入bean實例的屬性
applyBeanPropertyValues() : 注入bean實例的屬性值
initializeBean() : 初始化bean實例
applyBeanPostProcessorsBeforeInitialization() : 應用bean的前置處理
applyBeanPostProcessorsAfterInitialization() : 應用bean的后置處理
destroyBean() : 銷毀bean實例
SigletonBeanRegistry

這個接口定義了容器對單例的注冊管理方法。
方法說明:
registerSingleton() : 注冊bean
getSingleton() : 獲取bean
containsSingleton() : 返回是否包含bean
getSingletonNames() : 獲取bean實例(單例)的名稱數(shù)組
getSingletonCount() : 獲取容器中bean實例的總數(shù)
ConfigurableBeanFactory

這個接口繼承了SingletonBeanRegistry和HierarchicalBeanFactory兩個接口,增加了beanFactory的配置功能。主要是許多屬性的get和set方法。由于配置項較多,較為復雜,這里先不詳細介紹
ConfigurableListableBeanFactory

新增了忽略類型以及接口
總結
至此,已經了解完所有的相關接口,整理下所有的接口中定義的概念:
- Bean : 組件對象,sping容器所管理的對象
- SingletonBean : 特殊的bean,其在容器中僅有一個實例
- BeanDefinition : bean的配置清單,或者說定義文件,spring可以根據(jù)該文件實例化出對象
- Alias : bean的別名,一個bean可以有多個名稱
- BeanFactory : bean工廠,為其他組件提供管理容器

通過這個類圖,感覺整個BeanFactory生態(tài)圈已經構建起來了。不得不感嘆面向對象的魅力,僅僅是定義了接口,便展示了一個完整的功能模塊。
本文到這就要結束了,回顧下
1、首先是通過調試的方法,找到了整個bean管理功能模塊的核心DefaultListableBeanFactory
2、然后是對DefaultListableBeanFactory所實現(xiàn)的各個父級接口進行源碼閱讀和分析
3、最后再通過系統(tǒng)的整理出該功能模塊的概覽
通過以上三步,完成了BeanFactory的整個功能定義的概覽,下次會給大家?guī)淼氖侨绾我徊揭徊降?實現(xiàn)上述的定義
本文到此就結束,希望能夠幫到大家。
純屬原創(chuàng),轉載請聲明出處。
——作者:陳來件(QQ:810522442)