一直想把Spring源碼完整解析一遍,一直由於工作忙,上班沒有時間,下班呢,講實話,要我學習,簡直好難。偶爾被雞湯文灌一灌,會學習個兩三天,然後!!!又是迴歸原始狀態。我不知道你們是不是也是這樣,很多東西我看過記得兩三天,到時候一轉眼就忘記了,所以我想到自己寫博客來記錄一下,想看的時候就翻出來看一看。
我寫的所有博客都是會花大量時間去整理,儘可能通俗易懂,如果你覺得不錯,可以收藏,有時間就可以看看,畢竟是結合了很多博客的精髓,喜歡的話,請點贊或者評論,謝謝大家。
繼上次
Spring源碼解析(一)
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
// 進入this(new String[] {configLocation}, true, null)方法
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
//1.初始化父類,設置PathMatchingResourcePatternResolver(資源查找器,主要是獲取資源文件的時候可以解析*,?等符號的路徑)
super(parent);
//2.設置本地的配置信息
setConfigLocations(configLocations);
//3.spring容器的初始化
if (refresh) {
refresh();
}
}
spring最核心就是spring容器的初始化,也就是構造函數中refresh()方法,這個方法是在AbstractApplicationContext中
@Override
public void refresh() throws BeansException, IllegalStateException {
//startupShutdownMonitor對象在spring環境刷新和銷燬的時候都會用到,確保刷新和銷燬不會同時執行
synchronized (this.startupShutdownMonitor) {
// 準備工作,例如記錄事件,設置標誌,檢查環境變量等,並有留給子類擴展的位置,用來將屬性加入到applicationContext中
prepareRefresh();
// 創建beanFactory,這個對象作爲applicationContext的成員變量,可以被applicationContext拿來用, 並且解析資源(例如xml文件),取得bean的定義,放在beanFactory中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 對beanFactory做一些設置,例如類加載器、spel解析器、指定bean的某些類型的成員變量對應某些對象等
prepareBeanFactory(beanFactory);
try {
// 子類擴展用,可以設置bean的後置處理器(bean在實例化之後這些後置處理器會執行)
postProcessBeanFactory(beanFactory);
// 執行beanFactory後置處理器(有別於bean後置處理器處理bean實例,beanFactory後置處理器處理bean定義)
invokeBeanFactoryPostProcessors(beanFactory);
// 將所有的bean的後置處理器排好序,但不會馬上用,bean實例化之後會用到
registerBeanPostProcessors(beanFactory);
// 初始化國際化服務
initMessageSource();
// 創建事件廣播器
initApplicationEventMulticaster();
// 空方法,留給子類自己實現的,在實例化bean之前做一些ApplicationContext相關的操作
onRefresh();
// 註冊一部分特殊的事件監聽器,剩下的只是準備好名字,留待bean實例化完成後再註冊
registerListeners();
// 單例模式的bean的實例化、成員變量注入、初始化等工作都在此完成
finishBeanFactoryInitialization(beanFactory);
// applicationContext刷新完成後的處理,例如生命週期監聽器的回調,廣播通知等
finishRefresh();
}
catch (BeansException ex) {
logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
// 刷新失敗後的處理,主要是將一些保存環境信息的集合做清理
destroyBeans();
// applicationContext是否已經激活的標誌,設置爲false
cancelRefresh(ex);
// 拋出異常
throw ex;
}
}
}
prepareRefresh方法
prepareRefresh方法的源碼如下:
protected void prepareRefresh() {
//記錄初始化開始時間
this.startupDate = System.currentTimeMillis();
//context是否關閉的標誌,設置爲false
this.closed.set(false);
//context是否激活的標誌,設置爲true
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
//留給子類實現的空方法
initPropertySources();
/**
AbstractPropertyResolver類的requiredProperties是個集合,
在下面的validateRequiredProperties方法中,都要拿requiredProperties中的元素作爲key去檢查是否存在對應的環境變量,如果不存在就拋出異常
*/
getEnvironment().validateRequiredProperties();
//初始化早期application事件
this.earlyApplicationEvents = new LinkedHashSet<>();
}
- initPropertySources是個空方法,是留給子類實現的
protected void initPropertySources() {
// For subclasses: do nothing by default.
}
- getEnvironment().validateRequiredProperties();檢查某些必要的環境配置是否存在,不存在就拋出異常,這裏的environment就是ConfigurableEnvironment,我們在setConfigLocations(configLocations);這步時其實已經獲取過了。
@Override
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
getEnvironment().validateRequiredProperties();在ConfigurableEnvironment實現類AbstractEnvironment中
@Override
public void validateRequiredProperties() throws MissingRequiredPropertiesException {
//檢查必要的屬性是否存在,不存在就拋異常
this.propertyResolver.validateRequiredProperties();
}
繼續跟蹤validateRequiredProperties(),發現其實現在AbstractPropertyResolver類中
//必要的屬性
private final Set<String> requiredProperties = new LinkedHashSet<>();
@Override
public void validateRequiredProperties() {
//缺失必要屬性異常
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {
//如果在setConfigLocations(configLocations)這一步中放入的變量沒有必要的屬性,就添加到ex異常中
if (this.getProperty(key) == null) {
ex.addMissingRequiredProperty(key);
}
}
//如果異常的missingRequiredProperties集合不爲空,就證明有必要屬性不存在,就拋出這個異常
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
看完這裏,好像覺得沒什麼卵用,因爲是個空的集合,對吧?仔細想想,如果你在集合中添加了必要的屬性呢?那是不是就可以檢驗了。再想想之前initPropertySources空構造,那麼,如果我們實現AbstractApplicationContext,然後再重寫initPropertySources,再給requiredProperties設置必要屬性呢?
例:
@Override
protected void initPropertySources() {
getEnvironment().setRequiredProperties("env","test");
}
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
先看看類的繼承關係圖
再看看obtainFreshBeanFactory方法:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//由子類AbstractRefreshableApplicationContext創建beanFactory
refreshBeanFactory();
//取得子類創建好的beanFactory,作爲obtainFreshBeanFactory方法的返回值返回
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
refreshBeanFactory方法
refreshBeanFactory方法,在AbstractApplicationContext類中是抽象方法,具體實現在子類中,其子類AbstractRefreshableApplicationContext爲例,我們來看看refreshBeanFactory方法的實現:
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果beanFactory已經存在,就銷燬context管理的所有bean,並關閉beanFactory
if (hasBeanFactory()) {
//其實就是調用一些集合的clear方法,解除對一些實例的引用,參考DefaultSingletonBeanRegistry.destroySingletons方法
destroyBeans();
//關閉當前的beanFactory,其實就是將成員變量beanFactory設置爲null
closeBeanFactory();
}
try {
// 爲了序列話指定id,如果需要的話,讓這個BeanFactory從id反序列化到BeanFactory對象
beanFactory.setSerializationId(getId());
/**
* 設置兩個屬性:
* 1. 是否允許覆蓋同名稱的不同定義的對象
* 2. 是否允許bean之間存在循環依賴
*/
customizeBeanFactory(beanFactory);
// 初始化DocumentReader,並進行XML文件讀取和解析
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
createBeanFactory方法實際上返回的是一個ConfigurableListableBeanFactory 實現類DefaultListableBeanFactory實例
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
//跟蹤DefaultListableBeanFactory父類AbstractAutowireCapableBeanFactory,忽略一些接口
public AbstractAutowireCapableBeanFactory() {
super();
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
customizeBeanFactory方法是留給子類OverWrite
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
//allowBeanDefinitionOverriding表示是否允許註冊一個同名的類來覆蓋原有類(注意是類,不是實例)
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
//allowCircularReferences表示是否運行多個類之間的循環引用
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
這裏和上面檢查必要屬性一樣,可以重寫這個方法,然後設置這兩個屬性
例:
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
super.setAllowBeanDefinitionOverriding(false);
super.setAllowCircularReferences(false);
super.customizeBeanFactory(beanFactory);
}
在AbstractXmlApplicationContext中loadBeanDefinitions()會初始化DocumentReader,並進行XML文件讀取和解析
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 爲指定beanFactory創建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 對beanDefinitionReader進行環境變量的設置
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 對beanDefinitionReader進行設置,可以覆蓋
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
//loadBeanDefinitions(beanDefinitionReader);
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
/**
* 到底是configLocations 還是configResources ,和我們使用哪個構造方法來實例化applicationContext對象有關
* 我們用的是new ClassPathXmlApplicationContext(“applicationContext.xml”),那麼setConfigLocations方法就會被調用
**/
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
//reader.loadBeanDefinitions(configLocations);
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int counter = 0;
for (String location : locations) {
counter += loadBeanDefinitions(location);
}
return counter;
}
//loadBeanDefinitions(location)
@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
//loadBeanDefinitions(location, null);
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int loadCount = loadBeanDefinitions(resources);
if (actualResources != null) {
for (Resource resource : resources) {
actualResources.add(resource);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
}
return loadCount;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
}
else {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int loadCount = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
}
return loadCount;
}
}
//重點在loadBeanDefinitions(resources)
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
counter += loadBeanDefinitions(resource);
}
return counter;
}
//進入XmlBeanDefinitionReader中的loadBeanDefinitions(resource)
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
//loadBeanDefinitions(new EncodedResource(resource));
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
//doLoadBeanDefinitions(inputSource, encodedResource.getResource());
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//解析resource獲取Document
Document doc = doLoadDocument(inputSource, resource);
//註冊BeanDefinition
return registerBeanDefinitions(doc, resource);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
//
上面這麼一長串代碼,其實就是一路跟蹤,最後到了重點registerBeanDefinitions(doc, resource);
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//創建BeanDefinition的Document Reader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//獲取已經解析了的BeanDefiniton的數目
int countBefore = getRegistry().getBeanDefinitionCount();
//使用reource創建reader的上下文,註冊當前的BeanDefinition
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
//documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//子類DefaultBeanDefinitionDocumentReader中
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
//真正register BeanDefinition的入口
doRegisterBeanDefinitions(root);
}
// doRegisterBeanDefinitions(root);
protected void doRegisterBeanDefinitions(Element root) {
//嵌套的<beans>將遞歸調用這個方法,爲了能夠傳播和保存<beans>的default-*屬性,需要跟蹤當前的委託
//初始的委託爲null
BeanDefinitionParserDelegate parent = this.delegate;
//創建委託,並初始化default-*屬性
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//供子類使用,作爲前置處理
preProcessXml(root);
//使用委託從root節點解析BeanDefinition
parseBeanDefinitions(root, this.delegate);
//供子類使用,作爲後置處理
postProcessXml(root);
this.delegate = parent;
}
//parseBeanDefinitions(root, this.delegate);
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//判斷是否是默認的namespace
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)) {
//解析默認的element
parseDefaultElement(ele, delegate);
}
else {
//解析自定義的element
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
//parseDefaultElement(ele, delegate);
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//處理import節點
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
//處理alias節點
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
//處理bean節點
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
//處理嵌套的beans節點
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// 此處會引入之前所說的遞歸
doRegisterBeanDefinitions(ele);
}
}
//processBeanDefinition(ele, delegate);
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//解析element,獲得一個BeanDefinitionHolder作爲BeanDefinition的容器,內有BeanDefinition、name和alias,這個方法詳細解析了對應element的各個attribute,如autowired,scope等;同時,還解析了其的子節//點,如constructor,property等
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//對BeanDefinitionHolder進行裝飾,作爲最終要註冊進BeanFactory的實例,此處裝飾的作用是解析一些自//定義的標籤
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 此處將BeanDefinitionHolder註冊進入registry,也就是示例代碼中的//DefaultListableBeanFactory
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
//BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
//維護了一個beanDefinitionMap,其鍵值對形式爲beanName->BeanDefinition,這是一個ConcurrentHashMap。注意,這個map維護的只是BeanDefinition,而不是bean。
//BeanDefinition是用來描述bean的,舉個例子:汽車就好比是bean 汽車有四個輪子,汽車是紅色的。。。這就是beanDefinition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
////維護了一個aliasMap,其鍵值對形式爲alias->beanName,這也是一個ConcurrentHashMap
registry.registerAlias(beanName, alias);
}
}
}
至此,refreshBeanFactory方法分析完畢,該方法所做的事情:把xml文件中的bean定義被解析後,beanName存放在DefaultListableBeanFactory的beanDefinitionMap中,alias存放在DefaultListableBeanFactory的aliasMap中;
prepareBeanFactory
接下來是prepareBeanFactory(beanFactory),看一下此方法的源碼:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//設置beanFactory的classLoader爲當前context的classLoader
beanFactory.setBeanClassLoader(getClassLoader());
//設置beanFactory的表達式語言處理器,Spring3增加了表達式語言的支持,SPEL語言。
//默認可以使用#{bean.xxx}的形式來調用相關屬性值。
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//爲beanFactory增加了一個默認的propertyEditor,這個主要是對bean的屬性等設置管理的一個工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//添加BeanPostProcessor
//ApplicationContextAwareProcessor實現了BeanPostProcessor接口,在bean實例化的時候會被調用postProcessBeforeInitialization
//postProcessBeforeInitialization方法中調用了invokeAwareInterfaces。從invokeAwareInterfaces方法中,我們可以看出來,實現這些Aware接口的bean在被初始化之後,可以取得一些對應的資源。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//Spring將ApplicationContextAwareProcessor註冊後,在invokeAwareInterfaces方法中間調用的Aware類已經不是普通的bean了,
//如ResourceLoaderAware,ApplicationEventPublisherAware等,需要在Spring做bean的依賴注入的時候忽略它們。
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
//設置了幾個自動裝配的特殊規則
//當註冊了依賴解析後,例如當註冊了對BeanFactory.class的解析後,當bean的屬性注入的時候,
//一旦檢測到屬性爲BeanFactory類型便會將beanFactory的實例注入進去。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//增加對AspectJ的支持,也是就用於AOP靜態代理相關的處理
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()));
}
//將相關環境變量及屬性註冊以單例模式註冊,environment,systemProperties,systemEnvironment
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
總的來說prepareBeanFactory方法就是爲beanFactory做一些設置工作,傳入一些後面會用到的參數和工具類,再在spring容器中創建一些單例的bean.
postProcessBeanFactory
postProcessBeanFactory方法是留給子類擴展的,可以在bean實例初始化之前註冊後置處理器(類似prepareBeanFactory方法中的beanFactory.addBeanPostProcessor),以子類AbstractRefreshableWebApplicationContext爲例,其postProcessBeanFactory方法如下:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
可見除了WebApplicationContextUtils類的工作之外,其餘的都是和prepareBeanFactory方法中類似的處理;
invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors方法用來執行BeanFactory實例的後置處理器BeanFactoryPostProcessor的postProcessBeanFactory方法,這個後置處理器除了原生的,我們也可以自己擴展,用來對Bean的定義做一些修改,由於此時bean還沒有實例化,所以不要在自己擴展的BeanFactoryPostProcessor中調用那些會觸發bean實例化的方法(例如BeanFactory的getBeanNamesForType方法),源碼的文檔中有相關說明,如下圖紅框所示,不要觸發bean的實例化,如果要處理bean實例請在BeanPostProcessor中進行;
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* getBeanFactoryPostProcessors獲取自定義的beanFactoryPostProcessor
* 何爲自定義?
* 不通過註解形式掃描獲取
* 而是通過手動context.addBeanFactoryPostProcessor(beanFactoryPostProcessor)完成自定義
*
* getBeanFactoryPostProcessors默認是個空的List
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
/**
* 如果發現loadTimeWeaver的Bean
* 添加BeanPostProcessor->LoadTimeWeaverAwareProcessor
*/
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
getBeanFactoryPostProcessors()
這裏的getBeanFactoryPostProcessors()就是單純的通過addBeanFactoryPostProcessor方法添加的BFPP
/** BeanFactoryPostProcessors to apply on refresh */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
@Override
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
*/
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}
invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
// 1.判斷beanFactory是否爲BeanDefinitionRegistry,beanFactory爲DefaultListableBeanFactory,
// 而DefaultListableBeanFactory實現了BeanDefinitionRegistry接口,因此這邊爲true
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 用於存放普通的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
// 用於存放BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
// 2.首先處理入參中的beanFactoryPostProcessors
// 遍歷所有的beanFactoryPostProcessors, 將BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor區分開
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
// 2.1 如果是BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 2.1.1 直接執行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 2.1.2 添加到registryProcessors(用於最後執行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
} else {
// 2.2 否則,只是普通的BeanFactoryPostProcessor
// 2.2.1 添加到regularPostProcessors(用於最後執行postProcessBeanFactory方法)
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 用於保存本次要執行的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 3.調用所有實現PriorityOrdered接口的BeanDefinitionRegistryPostProcessor實現類
// 3.1 找出所有實現BeanDefinitionRegistryPostProcessor接口的Bean的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 3.2 遍歷postProcessorNames
for (String ppName : postProcessorNames) {
// 3.3 校驗是否實現了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 3.4 獲取ppName對應的bean實例, 添加到currentRegistryProcessors中,
// beanFactory.getBean: 這邊getBean方法會觸發創建ppName對應的bean對象, 目前暫不深入解析
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 3.5 將要被執行的加入processedBeans,避免後續重複執行
processedBeans.add(ppName);
}
}
// 3.6 進行排序(根據是否實現PriorityOrdered、Ordered接口和order值來排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 3.7 添加到registryProcessors(用於最後執行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);
// 3.8 遍歷currentRegistryProcessors, 執行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3.9 執行完畢後, 清空currentRegistryProcessors
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 4.調用所有實現了Ordered接口的BeanDefinitionRegistryPostProcessor實現類(過程跟上面的步驟3基本一樣)
// 4.1 找出所有實現BeanDefinitionRegistryPostProcessor接口的類, 這邊重複查找是因爲執行完上面的BeanDefinitionRegistryPostProcessor,
// 可能會新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 校驗是否實現了Ordered接口,並且還未執行過
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 4.2 遍歷currentRegistryProcessors, 執行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 5.最後, 調用所有剩下的BeanDefinitionRegistryPostProcessors
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 5.1 找出所有實現BeanDefinitionRegistryPostProcessor接口的類
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 5.2 跳過已經執行過的
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
// 5.3 如果有BeanDefinitionRegistryPostProcessor被執行, 則有可能會產生新的BeanDefinitionRegistryPostProcessor,
// 因此這邊將reiterate賦值爲true, 代表需要再循環查找一次
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 5.4 遍歷currentRegistryProcessors, 執行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 6.調用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor繼承自BeanFactoryPostProcessor)
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 7.最後, 調用入參beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 到這裏 , 入參beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已經全部處理完畢,
// 下面開始處理容器中的所有BeanFactoryPostProcessor
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 8.找出所有實現BeanFactoryPostProcessor接口的類
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 用於存放實現了PriorityOrdered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
// 用於存放實現了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<String>();
// 用於存放普通BeanFactoryPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
// 8.1 遍歷postProcessorNames, 將BeanFactoryPostProcessor按實現PriorityOrdered、實現Ordered接口、普通三種區分開
for (String ppName : postProcessorNames) {
// 8.2 跳過已經執行過的
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 8.3 添加實現了PriorityOrdered接口的BeanFactoryPostProcessor
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 8.4 添加實現了Ordered接口的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
} else {
// 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 9.調用所有實現PriorityOrdered接口的BeanFactoryPostProcessor
// 9.1 對priorityOrderedPostProcessors排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 9.2 遍歷priorityOrderedPostProcessors, 執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 10.調用所有實現Ordered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
// 10.1 獲取postProcessorName對應的bean實例, 添加到orderedPostProcessors, 準備執行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 10.2 對orderedPostProcessors排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 10.3 遍歷orderedPostProcessors, 執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
// 11.調用所有剩下的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 11.1 獲取postProcessorName對應的bean實例, 添加到nonOrderedPostProcessors, 準備執行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 11.2 遍歷nonOrderedPostProcessors, 執行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 12.清除元數據緩存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因爲後處理器可能已經修改了原始元數據,例如, 替換值中的佔位符...
beanFactory.clearMetadataCache();
}
總結一下上方的邏輯:
1.將BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,分別放入兩個集合
分別進行排序處理
2.按照優先級分別調用invokeBeanDefinitionRegistryPostProcessors和invokeBeanFactoryPostProcessors方法
3.這兩個invoke方法相信你可以想象的到無非就是循環調用這些實現類對應的方法
invokeBeanFactoryPostProcessors
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
所以這裏BeanFactoryPostProcessors就會執行postProcessBeanFactory方法
registerBeanPostProcessors
registerBeanPostProcessors方法簡單的說,就是找出所有的bean的後置處理器(注意,是bean的後置處理器,不是beanFactory的後置處理器,bean後置處理器處理的是bean實例,beanfactory後置處理器處理的是bean的定義),然後將這些bean的後置處理器分爲三類:
1.實現了順序接口Ordered.class的,先放入orderedPostProcessors集合,排序後順序加入beanFactory的bean後處理集合中;
2. 既沒有實現Ordered.class,也沒有實現PriorityOrdered.class的後置處理器,也加入到beanFactory的bean後處理集合中;
3. 最後是實現了優先級接口PriorityOrdered.class的,排序後順序加入beanFactory的bean後處理集合中;
registerBeanPostProcessors方法執行完畢後,beanFactory中已經保存了有序的bean後置處理器,在bean實例化之後,會依次使用這些後置處理器對bean實例來做對應的處理;
/**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 查詢需要註冊的BeanPostProcessor的實現類
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 通過BeanPostProcessorChecker來檢查一個bean沒有合理的創建,內部通過打印日誌信息記錄
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 分類處理BeanPostProccesor的初始化優先級,分別爲PriorityOrdered > Ordered > 普通的BeanPostProccesor,
// 然後排序放入BeanFactory的beanPostProcessors中去。
// 提供給其他處初始化需要增強的Bean。如果BeanPostProccessor中注入了沒有實現BeanPostProccessor的bean。
// 那麼注入的類會提前初始化。常見的就是集成Shiro的時候。
// ShiroFilterFactoryBean初始化的時候,其中注入的bean都會提前初始化,如Realm注入的是Service的話,那麼該Service就不會被事務代理。
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 用來檢測實現ApplicationListener接口的Bean
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
initMessageSource
initMessageSource方法用來準備國際化資源相關的,將實現了MessageSource接口的bean存放在ApplicationContext的成員變量中,先看是否有配置,如果有就實例化,否則就創建一個DelegatingMessageSource實例的bean
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//messageSource
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
//如果在配置中已經配置了messageSource,那麼將messageSource提取並記錄在this.messageSource中
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
//如果用戶並沒有定義配置文件,那麼使用臨時的DelegatingMessageSource以便於作爲調用getMessage方法的返回。
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
initApplicationEventMulticaster
spring中有事件、事件廣播器、事件監聽器等組成事件體系,在initApplicationEventMulticaster方法中對事件廣播器做初始化,如果找不到此bean的配置,就創建一個SimpleApplicationEventMulticaster實例作爲事件廣播器的bean,並且保存爲applicationContext的成員變量applicationEventMulticaster;
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
/**
* 判斷容器中是否存在bdName爲applicationEventMulticaster的bd
* 也就是自定義的事件監聽多路廣播器,必須實現ApplicationEventMulticaster接口
*/
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
/**
* 如果沒有,則默認採用SimpleApplicationEventMulticaster
*/
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
onRefresh
onRefresh是個空方法,留給子類自己實現的,在實例化bean之前做一些ApplicationContext相關的操作,以子類AbstractRefreshableWebApplicationContext爲例,看看它的onRefresh方法:
@Override
protected void onRefresh() {
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
registerListeners
方法名爲registerListeners,看名字像是將監聽器註冊在事件廣播器中,但實際情況並非如此,只有一些特殊的監聽器被註冊了,那些在bean配置文件中實現了ApplicationListener接口的類還沒有實例化,所以此處只是將其name保存在廣播器中,將這些監聽器註冊在廣播器的操作是在bean的後置處理器中完成的,那時候bean已經實例化完成了,我們看代碼:
protected void registerListeners() {
//硬編碼方式註冊的監聽器處理
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
//配置文件註冊的監聽器處理
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
//廣播早期的事件進行廣播和事件處理
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
//initApplicationEventMulticaster方法的廣播器進行廣播
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
按照之前介紹的順序及邏輯,作爲廣播器,一定是用於存放監聽器並在合適的時候調用監聽器,那麼進入默認的廣播器實現SimpleApplicationEventMulticaster來一探究竟。
@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
listener.onApplicationEvent(event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
listener.onApplicationEvent(event);
}
}
可以推斷,當產生Spring事件發生的時候會默認使用SimpleApplicationEventMulticaster的multicastEvent來廣播事件,遍歷所有監聽器,並使用監聽器中的onApplicationEvent方法來進行監聽器的處理。而對於每個監聽器來說其實都可以獲取到產生的事件,但是是否進行處理則由事件監聽器來決定。
finishBeanFactoryInitialization
完成BeanFactory的初始化工作,其中包括ConversionService的設置、配置凍結以及非延遲加載的bean的初始化工作。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//conversionService的bean會被註冊
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));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
//凍結所有的bean定義,說明註冊的bean定義將不被修改或任何進一步的處理。
beanFactory.freezeConfiguration();
//初始化剩下的單實例(非惰性的)
beanFactory.preInstantiateSingletons();
}
ConversionService的設置,之前我們提到過使用自定義類型轉換器從String轉換爲Date的方式,使用屬性編輯器,那麼,在Spring中還提供了另一種轉換方式:使用Converter。
ApplicationContext實現的默認行爲就是在啓動時將所有單例bean提前進行實例化。提前實例化意味着作爲初始化過程的一部分,ApplicationContext實例會創建並配置所有的單例bean。通常情況下這是一件好事,因爲這樣在配置中的任何錯誤就會即刻被發現(否則的話可能要花幾個小時甚至幾天)。而這個實例化的過程就是在finishBeanFactoryInitialization中完成的
finishRefresh
最後一個方法是finishRefresh,這是在bean的實例化、初始化等完成後的一些操作,例如生命週期變更的回調,發送applicationContext刷新完成的廣播等,展開看看:
protected void finishRefresh() {
// 檢查是否已經配置了生命週期處理器,如果沒有就new一個DefaultLifecycleProcessor
initLifecycleProcessor();
// 找到所有實現了Lifecycle接口的bean,按照每個bean設置的生命週期階段進行分組,再依次調用每個分組中每個bean的start方法,完成生命週期監聽的通知
getLifecycleProcessor().onRefresh();
// 創建一條代表applicationContext刷新完成的事件,交給廣播器去廣播
publishEvent(new ContextRefreshedEvent(this));
// 如果配置了MBeanServer,就完成在MBeanServer上的註冊
LiveBeansView.registerApplicationContext(this);
}
destroyBeans
獲取beanFactory,並銷燬單例的bean
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
@Override
public void destroySingletons() {
super.destroySingletons();
// 清除記錄的單例beanName的緩存
this.manualSingletonNames.clear();
clearByTypeCache();
}
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
// 這裏使用ConcurrentHashMap本地緩存單例的bean實例,訪問次數比較多,提搞併發量
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
// 這裏是用LinkedHashMap本地緩存銷燬的bean實例
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
// 銷燬單例的bean
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
// 同步清空緩存
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.刪除單例的bean,從本地緩存中刪除
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
// 從本地緩存中刪除
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
// bean銷燬的邏輯
destroyBean(beanName, disposableBean);
}
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first... 先觸發依賴的bean銷燬,從本地緩存中刪除
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
// 這裏用了一個遞歸刪除單例bean,當這個bean沒有依賴的bean要刪除的時候,遞歸結束
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now... 這裏開始刪除單例bean
if (bean != null) {
try {
// bean可以實現DisposableBean這個接口,重寫父類的bean destory的方法
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
// Trigger destruction of contained beans...從本地緩存中銷燬內部bean
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
// 這個地方還是遞歸調用,刪除單例bean,當這個bean沒有內部bean時遞歸結束
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies. 從其他bean依賴中刪除銷燬的bean
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.刪除銷燬的bean準備的依賴信息
this.dependenciesForBeanMap.remove(beanName);
}
如果要在一個bean銷燬的時候執行一些定製化的邏輯,有三種方式
1、在bean定義中bean標籤中destory-method指定
2、實現DisposableBean將誒口,重寫destory方法
3、在bean的方法上加上@PreDestroy註解
cancelRefresh
refresh失敗時,設置active標誌=false
protected void cancelRefresh(BeansException ex) {
this.active.set(false);
}
resetCommonCaches
重置Spring核心中的常見內核緩存,因爲我們可能不再需要單例bean的元數據了
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
最後總結一遍refresh總共幹了些啥:
1.環境準備
2.加載BeanFactory
3.功能擴展
4.BeanFactory的後處理
5.激活BeanFactoryPostProcessor
6.註冊BeanPostProcessor
7.初始化消息資源
8.初始化ApplicationEventMulticaster
9.註冊監聽器
10.初始化非延遲加載單例
11.finishRefresh