一、示例代碼
整體代碼工程目錄如下

首先我們新建一個(gè)類Man
public class Man {
public void say(String content){
System.out.println("say: "+content);
}
}
然后我們新建一個(gè)main方法類,通過new一個(gè)ClassPathXmlApplicationContext,來(lái)加載Man
public class App
{
public static void main( String[] args )
{
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
Man man = (Man)ac.getBean("man");
man.say("hello world");
}
}
application.xml內(nèi)容如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<bean name="man" class="XmlApplicationContext.Man" />
</beans>
二、源碼入口
通過斷點(diǎn),發(fā)現(xiàn)在ClassPathXmlApplicationContext構(gòu)造器里面,最終調(diào)用了refresh
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
最關(guān)鍵就是其中的refresh()方法,接下來(lái),我們一步一步進(jìn)行分析。
三、refresh整體盤點(diǎn)
3.1 類關(guān)系
refresh方法的具體實(shí)現(xiàn)代碼是在ClassPathXmlApplicationContext的父類AbstractApplicationContext#refresh
這里提下繼承關(guān)系:
ClassPathXmlApplicationContext -> AbstractXmlApplicationContext -> AbstractRefreshableConfigApplicationContext -> AbstractRefreshableApplicationContext -> AbstractApplicationContext
可以看到繼承的鏈路還是很長(zhǎng)的
3.2 代碼實(shí)現(xiàn)
下面看AbstractApplicationContext#refresh實(shí)現(xiàn)代碼,直接上源碼
public void refresh() throws BeansException, IllegalStateException {
// 首先加鎖, 防并發(fā)
synchronized (this.startupShutdownMonitor) {
// 1 初始化一些變量
prepareRefresh();
// 2 生成父類DefaultListableBeanFactory,并解析xml生成BeanDefinition緩存
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3 設(shè)置beanFactory的類加載器,回調(diào),事件消息等
prepareBeanFactory(beanFactory);
try {
// 4 空實(shí)現(xiàn)
postProcessBeanFactory(beanFactory);
// 5 執(zhí)行beanFactory的所有回調(diào)
invokeBeanFactoryPostProcessors(beanFactory);
// 6 bean初始化時(shí)涉及的回調(diào)
registerBeanPostProcessors(beanFactory);
// 7 國(guó)際化資源
initMessageSource();
// 8 初始化事件多播器
initApplicationEventMulticaster();
// 9 空實(shí)現(xiàn)
onRefresh();
// 10 注冊(cè)監(jiān)聽器,執(zhí)行那些在監(jiān)聽器注冊(cè)完成前的,早期事件earlyApplicationEvents
// 實(shí)現(xiàn)代碼位置AbstractApplicationContext
registerListeners();
// 11 對(duì)非懶加載singleton bean實(shí)例化,初始化LoadTimeWeaverAware beans
finishBeanFactoryInitialization(beanFactory);
// 12 清緩存+初始化LifecycleProcessor+發(fā)送ApplicationContext刷新事件+注冊(cè)ApplicationContext
finishRefresh();
}
catch (BeansException ex) {
。。。。。。
// 初始化失敗,則釋放bean緩存
destroyBeans();
。。。。。。
}
。。。。。。
}
}
上面注釋的12步,是ApplicationContext初始化的核心流程。注意refresh方法,所有操作,是在對(duì)startupShutdownMonitor加鎖的情況下執(zhí)行。也就是說(shuō)ApplicationContext初始化和銷毀時(shí),都是必須先加鎖,后操作。
四、逐個(gè)擊破
源碼位于AbstractApplicationContext#refresh,下面我們逐個(gè)方法分析,看看spring如何完成初始化的。
4.1 prepareRefresh
如下源碼,可以看到如方法名一樣,主要做些事前準(zhǔn)備工作。
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
。。。。。。
// 空實(shí)現(xiàn)
initPropertySources();
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
}
4.2 生成beanFactory
4.2.1 主方法
首先生成了一個(gè)beanFactory,然后再把此beanFactory作為返回值return
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
4.2.2 refreshBeanFactory方法
refreshBeanFactory方法的代碼不再位于AbstractApplicationContext中,代碼位于AbstractRefreshableApplicationContext#refreshBeanFactory。代碼中首先嘗試釋放老的beanFactory,然后new一個(gè)新的beanFactory,最后從xml中加載所有的BeanDefinitions。也就是這里不僅僅是new一個(gè)beanFactory這么簡(jiǎn)單,還順便把所有的xml解析了一遍。
protected final void refreshBeanFactory() throws BeansException {
// 1 如果有,則釋放老的beanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
。。。。。。
// 2 創(chuàng)建新的beanFactory,并初始化BeanDefinitions
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 3 設(shè)置bean重復(fù)定義和循環(huán)依賴的處理策略
customizeBeanFactory(beanFactory);
// 4 解析BeanDefinitions
loadBeanDefinitions(beanFactory);
。。。。。。
}
4.2.3 解析BeanDefinitions
loadBeanDefinitions的實(shí)現(xiàn)代碼位于AbstractXmlApplicationContext#loadBeanDefinitions。首先new了一個(gè)XmlBeanDefinitionReader,然后設(shè)置了xml解析器ResourceEntityResolver,最后調(diào)用loadBeanDefinitions解析bean。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1 初始化
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
// 2 解析
loadBeanDefinitions(beanDefinitionReader);
}
繼續(xù)往下跟蹤代碼,loadBeanDefinitions方法的代碼實(shí)現(xiàn)位于當(dāng)前類
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 代碼走到了這里
reader.loadBeanDefinitions(configLocations);
}
}
繼續(xù)跟蹤,reader.loadBeanDefinitions實(shí)現(xiàn)代碼位于AbstractBeanDefinitionReader#loadBeanDefinitions。代碼很簡(jiǎn)單,主要是解析后記了個(gè)數(shù)counter
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
。。。。。。
int counter = 0;
for (String location : locations) {
counter += loadBeanDefinitions(location);
}
return counter;
}
中間經(jīng)過若干名字類似的方法,因?yàn)闆]有實(shí)際處理邏輯,這里就不在贅述。最終走到了XmlBeanDefinitionReader#doLoadBeanDefinitions方法中,可以看到source被轉(zhuǎn)成了Document,然后調(diào)用registerBeanDefinitions,解析bean。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}
。。。。。。
}
繼續(xù)跟蹤當(dāng)前類中的registerBeanDefinitions,記錄下實(shí)際注冊(cè)的bean個(gè)數(shù)
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 解析bean
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
最終代碼走到了DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions中,這里終于看到了bean處理的流程
protected void doRegisterBeanDefinitions(Element root) {
。。。。。。
// 1 初始化bean解析器BeanDefinitionParserDelegate
this.delegate = createDelegate(getReaderContext(), root, parent);
。。。。。。
// 2 空實(shí)現(xiàn)
preProcessXml(root);
// 3 解析bean
parseBeanDefinitions(root, this.delegate);
// 4 空實(shí)現(xiàn)
postProcessXml(root);
。。。。。。
}
第3步parseBeanDefinitions實(shí)現(xiàn)代碼,在當(dāng)前類中??梢钥吹较旅媸?,遍歷處理xml節(jié)點(diǎn),最終我們的bean解析執(zhí)行到了parseDefaultElement(ele, delegate);方法中
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// 代碼走到了這里
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
看下parseDefaultElement代碼實(shí)現(xiàn),代碼分別解析了import,alias,bean以及beans
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
// 代碼走到了這里
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
繼續(xù)跟蹤processBeanDefinition方法,其中decorateBeanDefinitionIfRequired是真正解析xml的地方,在前面3步完成bean解析注冊(cè)后,還會(huì)發(fā)送一個(gè)內(nèi)部bean注冊(cè)完成的事件。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 1 這里才真正的解析了xml,生成BeanDefinition
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 2 解析自定義標(biāo)簽
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 3 注冊(cè)bean
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 4 發(fā)送bean注冊(cè)事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
我們先看下上面第1步的簡(jiǎn)要代碼,解析代碼位于BeanDefinitionParserDelegate#parseBeanDefinitionElement。最終解析為了一個(gè)包含BeanDefinition的BeanDefinitionHolder對(duì)象。
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 1 可以看到這里真正開始解析xml元素
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
。。。。。。
// 2 這里比較重要,實(shí)際生成的是子類GenericBeanDefinition
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
。。。。。。
// 3 返回值,包了一個(gè)BeanDefinitionHolder對(duì)象
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
。。。。。。
}
接下來(lái)看上面第3步的注冊(cè)bean,代碼位于BeanDefinitionReaderUtils#registerBeanDefinition,做了兩次注冊(cè),分別是通過beanName和通過別名注冊(cè)到DefaultListableBeanFactory中。其中registry對(duì)象就是前面的DefaultListableBeanFactory。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 1 通過beanName注冊(cè)
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 2 通過別名注冊(cè)
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
接下來(lái)我們分別可看下,這兩次注冊(cè),都做了什么事情。
首先看下第1步的“通過beanName注冊(cè)”,跟蹤到DefaultListableBeanFactory#registerBeanDefinition(String beanName, BeanDefinition beanDefinition)代碼中。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
。。。。。。
// 1 從緩存獲取BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
。。。。。。
// 1.1 如果允許覆蓋,重復(fù)定義后,這里會(huì)覆蓋掉原來(lái)的beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
。。。。。。
}
else {
// 1.2 有兩個(gè)緩存,beanDefinitionMap和beanDefinitionNames
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
。。。。。。
}
。。。。。。
}
上面兩個(gè)緩存beanDefinitionMap和beanDefinitionNames都定義在DefaultListableBeanFactory中。
接下來(lái)繼續(xù),第2步的“通過別名注冊(cè)”,跟蹤到SimpleAliasRegistry#registerAlias代碼中。
public void registerAlias(String name, String alias) {
。。。。。。
// 1 不允許有循環(huán)依賴
checkForAliasCircle(name, alias);
// 2 緩存起來(lái)
this.aliasMap.put(alias, name);
。。。。。。
}
至此bean的注冊(cè)代碼分析完了,我們?cè)倩仡櫹轮暗淖?cè)代碼。下面的代碼,實(shí)際上用到了三處緩存,分別是DefaultListableBeanFactory中的beanDefinitionMap和beanDefinitionNames,以及SimpleAliasRegistry中的aliasMap緩存。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 1 通過beanName注冊(cè)
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 2 通過別名注冊(cè)
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
4.2.4 prepareBeanFactory
我們回到refresh方法中的第4步“設(shè)置beanFactory的類加載器,回調(diào),事件消息等”,第4補(bǔ)調(diào)用了prepareBeanFactory方法。整體代碼結(jié)構(gòu),還是比較清晰的,直接看注釋。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 1 設(shè)置類加載器,spel解析器等
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 2 設(shè)置一些beanfactory需要和忽略的回調(diào)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 3 依賴緩存
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 4 注冊(cè)內(nèi)部的early post-processor,這里主要處理一些bean的異步事件回調(diào)。具體實(shí)現(xiàn)看ApplicationListenerDetector代碼。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 5 注冊(cè)LoadTimeWeaver
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
。。。。。。
}
4.2.5 invokeBeanFactoryPostProcessors
執(zhí)行相關(guān)BeanFactory回調(diào),包含對(duì)接口BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor的實(shí)現(xiàn),以及LoadTimeWeaverAwareProcessor
4.2.6 registerBeanPostProcessors
注冊(cè)普通bean回調(diào)處理器,實(shí)現(xiàn)代碼位于PostProcessorRegistrationDelegate#registerBeanPostProcessors。主要做回調(diào)處理器的分類,排序和注冊(cè)。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1 獲取實(shí)現(xiàn)了BeanPostProcessor接口的類集合。這一步做了很多工作,后面會(huì)做分析
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 2 主要添加bean檢查回調(diào)處理器
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 省略的代碼做了些分類和排序
。。。。。。
// 3 注冊(cè)到AbstractBeanFactory.beanPostProcessors緩存中
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 4 注冊(cè)ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
接下來(lái),著重分析上面注釋中,第1步getBeanNamesForType方法。實(shí)現(xiàn)代碼位于DefaultListableBeanFactory#getBeanNamesForType中。
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
}
。。。。。。
}
繼續(xù)跟蹤至當(dāng)前類中的doGetBeanNamesForType方法。首先取出RootBeanDefinition,然后判斷是否是FactoryBean,最后檢查是否是指定接口實(shí)現(xiàn)。
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
。。。。。。
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name
// is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
// 1 從DefaultListableBeanFactory.beanDefinitionMap緩存中取出beanDefinition,然后包裝成返回值RootBeanDefinition,并放入AbstractBeanFactory.mergedBeanDefinitions緩存中
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// 2 判斷是否是FactoryBean
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
// 3 檢查是否實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口
boolean matchFound =
(allowEagerInit || !isFactoryBean ||
(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
(includeNonSingletons ||
(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
isTypeMatch(beanName, type);
if (!matchFound && isFactoryBean) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
BeanDefinitionRegistryPostProcessor
matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
}
if (matchFound) {
result.add(beanName);
}
}
}
。。。。。。
}
}
。。。。。。
return StringUtils.toStringArray(result);
}
我們繼續(xù)跟蹤上面第2步“判斷是否是FactoryBean”,下面代碼邏輯,先是生成了一個(gè)bean的class,然后判斷是否是FactoryBean的子類。
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}
那么上面代碼是如何生成bean class的呢?如果繼續(xù)跟蹤代碼,會(huì)發(fā)現(xiàn),最終生成類的代碼位于AbstractBeanDefinition#resolveBeanClass中,如下所示,通過工具類ClassUtils加載了class,而工具類ClassUtils里面實(shí)際使用了ClassLoader.loadClass或者Class.forName來(lái)加載bean class。
public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
String className = getBeanClassName();
if (className == null) {
return null;
}
Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
this.beanClass = resolvedClass;
return resolvedClass;
}
4.2.7 initMessageSource
國(guó)際化資源,忽略
4.2.8 initApplicationEventMulticaster
refresh方法中第8步是初始化事件多播器,因?yàn)閮H僅是簡(jiǎn)單示例代碼,會(huì)執(zhí)行else里面,注冊(cè)一個(gè)默認(rèn)的多播器。
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
。。。。。。
}
else {
// 注冊(cè)一個(gè)默認(rèn)的多播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
。。。。。。
}
}
4.2.9 onRefresh
空實(shí)現(xiàn)
4.2.10 registerListeners
refresh方法中第10步是注冊(cè)監(jiān)聽器。下面代碼可以發(fā)現(xiàn),第10步,不僅僅注冊(cè)了監(jiān)聽器,還處理了早期事件。
protected void registerListeners() {
// 1 注冊(cè)監(jiān)聽器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 2 發(fā)送早期事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
4.2.11 finishBeanFactoryInitialization
refresh方法中第11步是對(duì)非懶加載bean實(shí)例化。bean實(shí)例化還是比較復(fù)雜的,需要專門的一篇文章詳解。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
。。。。。。
// 對(duì)非懶加載bean實(shí)例化
beanFactory.preInstantiateSingletons();
}
繼續(xù)跟蹤代碼,位于DefaultListableBeanFactory#preInstantiateSingletons中。
public void preInstantiateSingletons() throws BeansException {
。。。。。。
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 1 遍歷實(shí)例化非懶加載bean
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
。。。。。。
}
else {
// 2 實(shí)例化
getBean(beanName);
}
}
}
。。。。。。
}
4.2.12 finishRefresh
最后做一波收尾工作,包含生命周期管理器,刷新事件以及注冊(cè)上下文等。
protected void finishRefresh() {
// 1 清緩存
clearResourceCaches();
// 2 注冊(cè)LifecycleProcessor
initLifecycleProcessor();
// 3 執(zhí)行上面的處理器
getLifecycleProcessor().onRefresh();
// 4 發(fā)送刷新的異步事件
publishEvent(new ContextRefreshedEvent(this));
// 5 注冊(cè)上下文
LiveBeansView.registerApplicationContext(this);
}