高級JAVA開發 Spring部分(Context源碼解析)
參考和摘自:
《spring源碼深度解析(第2版)》 郝佳
Spring Bean的生命週期 —附詳細流程圖及測試代碼
源碼分析:doCreateBean
有錯誤,請歡迎無情拍磚!~
我的郵箱:[email protected]
註釋源碼Git:https://github.com/tanguosheng/spring-framework
下載源碼看更舒服些~
Spring容器源碼解析
基於spring 5.0.x版本。
spring-context包提供了多種context以供使用,常見的例如:AnnotationConfigApplicationContext、ClassPathXmlApplicationContext等。ClassPathXmlApplicationContext是最基礎的Context構建方式,從它入手即可瞭解spring的工作原理。先貼一張類繼承圖:
spring框架設計非常巧妙,繼承與調用關係錯綜複雜,提前瞭解繼承關係以便分析代碼找到正確實現類,以下分析思路僅關注脈絡。
spring上下文基礎用法即:
new ClassPathXmlApplicationContext("applicationContext.xml").getBean("beanName");
看看new ClassPathXmlApplicationContext("applicationContext.xml")
都做了啥:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 把當前的父context設置進去,這裏是null
super(parent);
// 將外面塞進來的配置文件路徑設置進去,等待一會兒解析。
setConfigLocations(configLocations);
if (refresh) { // true
// 刷新。加載從這裏開始
refresh();
}
}
繼續探究refresh方法:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 1. 初始化前的準備工作,例如對系統屬性或者環境變量進行準備及驗證。
// 可以重寫其中的方法達到提前驗證某些變量是否存在的目的
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2. 初始化BeanFactory,並進行XML文件讀取。
// 在這裏驗證解析xml文件、註冊bean到容器中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3. 對BeanFactory進行各種功能填充。比如:
// 設置classLoader、增加#{bean.xxx}表達式語言的支持、增加默認propertyEditor工具、
// 設置忽略自動裝配的接口、增加AspectJ的支持、增加幾個默認系統環境bean
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4.子類覆蓋方法做額外處理。(框架設計,這裏是空方法)
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 5. 激活註冊的BeanFactoryPostProcessor處理器。
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 6. 註冊攔截bean創建的bean處理器,這裏只是註冊,真正的調用是在getBean時候。
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 7. 爲上下文初始化Message源,即對不同語言的消息體進行國際化處理。
initMessageSource();
// Initialize event multicaster for this context.
// 8. 初始化應用消息廣播器,並放入“applicationEventMulticaster”bean中。
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 9. 留給子類來初始化其他的bean。
onRefresh();
// Check for listener beans and register them.
// 10.在所有註冊的bean中查找listener bean,註冊到消息廣播器中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 11. 實例化剩下的單實例(非惰性的)。
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 12. 完成刷新過程,通知生命週期處理器lifecycleProcessor刷新過程,
// 同時發出ContextRefreshEvent通知別人。
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 銷燬已經創建的單例bean
destroyBeans();
// Reset 'active' flag.
// 重置active標籤
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// 重置Spring核心中的緩存
resetCommonCaches();
}
}
}
比較關心的步驟一一解讀:
步驟2:初始化BeanFactory、XML文件讀取。
// AbstractApplicationContext.java:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 刷新BeanFactory
refreshBeanFactory();
// 初始化BeanFactory,然後返回beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName()
+ ": " + beanFactory);
}
return beanFactory;
}
// AbstractRefreshableApplicationContext.java: refreshBeanFactory 方法
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果已經存在BeanFactory,銷燬已經生成好的bean並且關閉BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 創建BeanFactory(DefaultListableBeanFactory),標註爲 ①,下文貼代碼可以看到
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 設置BeanFactory的序列化ID
beanFactory.setSerializationId(getId());
// 在customizeBeanFactory方法中設置兩個布爾參數:
// allowBeanDefinitionOverriding、allowCircularReferences
// 標註爲 ② ,下文分析
customizeBeanFactory(beanFactory);
// 正式開始解析xml,標註爲 ③
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
// BeanFactory作爲成員變量被AbstractRefreshableApplicationContext類持有。
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException(
"I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
BeanFactory作爲成員變量被AbstractRefreshableApplicationContext類持有。
① 深入createBeanFactory方法:
protected DefaultListableBeanFactory createBeanFactory() {
// 可以看到創建的BeanFactory類型是DefaultListableBeanFactory
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
// new DefaultListableBeanFactory時把父BeanFactory傳進來並保存
public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
// 調用父類(AbstractAutowireCapableBeanFactory)構造
super(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
// 調用本地構造
this();
// 保存父BeanFactory
setParentBeanFactory(parentBeanFactory);
}
public AbstractAutowireCapableBeanFactory() {
// 繼續調用父類(AbstractBeanFactory)構造,這個構造是空的
super();
// 忽略三個接口依賴:BeanNameAware、BeanFactoryAware、BeanClassLoaderAware
// 這裏記錄下來三個類的class,
// 在後面的bean自動裝載時(byName、byType)會自動忽略裝載三個接口實現類的屬性
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
貼上一張DefaultListableBeanFactory的繼承圖,DefaultListableBeanFactory對象承擔了BeanFactory、BeanRegistry、AliasRegistry角色,在後續代碼中在不同場景下把它轉成各種接口類型來承擔各種角色,其實都是它自己…
② 深入customizeBeanFactory方法:
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
// allowBeanDefinitionOverriding:允許同名BeanDefinition覆蓋,
// 用applicationContext.setAllowBeanDefinitionOverriding(true);來設置
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
// allowCircularReferences:單例bean是否禁用循環依賴檢測
// 用applicationContext.setAllowCircularReferences(false); 來設置禁止,
// 設置後有循環依賴會提前拋異常;
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
③ loadBeanDefinitions方法正式開始解析xml,繼續深入分析:
// AbstractXmlApplicationContext.java:
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
// 用給定的 beanFactory(DefaultListableBeanFactory類型)
// 創建一個新的 XmlBeanDefinitionReader,單一職責,用Reader去解析文件
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
// 設置環境變量等參數
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
// 加載BeanDefinitions,主要邏輯在這裏邊,看下面代碼
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader)
throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
// loadBeanDefinitions方法的重載,把參數轉化成EncodedResource類型後解析
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// loadBeanDefinitions方法的重載,把參數轉化成EncodedResource類型後解析
reader.loadBeanDefinitions(configLocations);
}
}
以上兩處紅框代碼最終都會調用到:
XmlBeanDefinitionReader.java 中的loadBeanDefinitions(EncodedResource encodedResource)
方法。
解析及註冊BeanDefinition
以下分析的代碼是spring-beans、spring-core包下的代碼。spring-beans、spring-core包提供解析bean的基礎功能:讀取文件、解析文件生成BeanDefinition對象、裝載對象等。
記錄已加載過的資源,inputStream封裝成inputSource,進入解析部分,繼續深入doLoadBeanDefinitions方法。
// XmlBeanDefinitionReader.java:
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);
}
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 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();
}
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
// 獲取驗證模式並對xml進行校驗。校驗成功後加載xml得到Document對象。
// xml的格式定義文件有兩種DTD和XSD,
// 這裏會根據xml頭中的配置來取得校驗模式、格式定義文件進行校驗。不贅述,重點放到解析上。
Document doc = doLoadDocument(inputSource, resource);
// 對Document對象解析配置,其中有bean、beans、import、alias等標籤,註冊Bean信息。
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);
}
}
public int registerBeanDefinitions(Document doc, Resource resource)
throws BeanDefinitionStoreException {
// 方法內部用反射的方式實例化了DefaultBeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 記錄註冊前BeanDefinition個數
int countBefore = getRegistry().getBeanDefinitionCount();
// 註冊BeanDefinition,下文代碼分析這個方法
// createReaderContext創建Reader上下文,查看是如何創建的
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 返回註冊前後BeanDefinition個數差
return getRegistry().getBeanDefinitionCount() - countBefore;
}
// 創建Reader上下文,關注getNamespaceHandlerResolver()方法
public XmlReaderContext createReaderContext(Resource resource) {
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, getNamespaceHandlerResolver());
}
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
if (this.namespaceHandlerResolver == null) {
// 創建默認命名空間HandlerResolver,關注這個方法
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}
return this.namespaceHandlerResolver;
}
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
ClassLoader cl = (getResourceLoader() != null ?
getResourceLoader().getClassLoader() : getBeanClassLoader());
// 關注new DefaultNamespaceHandlerResolver時初始化了什麼
return new DefaultNamespaceHandlerResolver(cl);
}
// DefaultNamespaceHandlerResolver.java
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) {
/*
* DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers"
* 這個常量的註釋是:
* The location to look for the mapping files. Can be present in multiple JAR files.
* 查找映射文件的位置。可以存在於多個JAR文件中。
*/
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
public DefaultNamespaceHandlerResolver(
@Nullable ClassLoader classLoader, String handlerMappingsLocation) {
Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null");
// 設置classLoader
this.classLoader = (classLoader != null ?
classLoader : ClassUtils.getDefaultClassLoader());
// 設置handlerMappingsLocation = "META-INF/spring.handlers"
this.handlerMappingsLocation = handlerMappingsLocation;
}
"META-INF/spring.handlers"路徑是spring配置自定義標籤解析器留下的鉤子,程序讀取每個包下META-INF/spring.handlers文件,加載文件中配置的nameSpace和NamespaceHandler接口的直接或間接實現類,實現類中向容器中註冊用戶自己實現的BeanDefinitionParser接口的實現類來實現自定義標籤的解析。和spring.handlers文件配套配置的還有spring.schemas文件,它定義命名空間和xml schema(xsd或dtd文件)之間的關係。
< dubbo:xxx >、< tx:xxx >等標籤都是這樣實現的。
以上關於handlerMappingsLocation = "META-INF/spring.handlers"的分析先告一段落,自定義標籤解析時繼續分析。
例子參考:基於Spring開發——自定義標籤及其解析 感謝作者~~
registerBeanDefinitions()方法:
// DefaultBeanDefinitionDocumentReader.java:
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
// 讀取root節點
Element root = doc.getDocumentElement();
// root節點扔進去解析並註冊
doRegisterBeanDefinitions(root);
}
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
/*
* 在createDelegate方法中創建了BeanDefinitionParserDelegate對象,初始化委託對象時順帶着解析了:
* default-lazy-init: 指定<beans>元素下配置的所有bean默認的延遲初始化行爲
* default-merge: 指定<beans>元素下配置的所有bean默認的merge行爲
* default-autowire: 指定<beans>元素下配置的所有bean默認的自動裝配行爲
* default-init-method: 指定<beans>元素下配置的所有bean默認的初始化方法
* default-destroy-method: 指定<beans>元素下配置的所有bean默認的回收方法
* default-autowire-candidates: 指定<beans>元素下配置的所有bean默認是否作爲自動裝配的候選Bean
*/
this.delegate = createDelegate(getReaderContext(), root, parent);
/*
* 如果是默認命名空間,解析profile屬性。
* profile屬性可以作爲多套環境配置使用。
* 它可以理解爲我們在Spring容器中所定義的Bean的邏輯組名稱,
* 只有當這些Profile被激活的時候,纔會將Profile中所對應的Bean註冊到Spring容器中。
*/
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);
// 解析BeanDefinitions
parseBeanDefinitions(root, this.delegate);
// 空方法,框架設計留出,給子類繼承覆蓋用。
postProcessXml(root);
this.delegate = parent;
}
// 分情況解析標籤
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);
}
}
profile用法詳解:詳解Spring中的Profile 感謝作者~~
默認標籤解析
// DefaultBeanDefinitionDocumentReader.java:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
// 解析import標籤,例如:<import resource="customerContext.xml"/>
importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
// 解析alias標籤
processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
// 解析bean標籤
processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
// 解析beans標籤,遞歸調用doRegisterBeanDefinitions
doRegisterBeanDefinitions(ele);
}
}
import標籤解析:
例如:<import resource="customerContext.xml"/>
protected void importBeanDefinitionResource(Element ele) {
// 獲取resource屬性
String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
if (!StringUtils.hasText(location)) {
getReaderContext().error("Resource location must not be empty", ele);
return;
}
// Resolve system properties: e.g. "${user.dir}"
// 解析系統屬性,例如"${user.dir}"
location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);
Set<Resource> actualResources = new LinkedHashSet<>(4);
// Discover whether the location is an absolute or relative URI
// 判定location是絕對URI還是相對URI
boolean absoluteLocation = false;
try {
absoluteLocation = ResourcePatternUtils.isUrl(location)
|| ResourceUtils.toURI(location).isAbsolute();
} catch (URISyntaxException ex) {
// cannot convert to an URI, considering the location relative
// unless it is the well-known Spring prefix "classpath*:"
}
// Absolute or relative?
if (absoluteLocation) {
// 絕對路徑直接根據地址加載對應的配置文件
try {
// 遞歸調用bean的解析過程
int importCount = getReaderContext()
.getReader().loadBeanDefinitions(location, actualResources);
if (logger.isDebugEnabled()) {
logger.debug("Imported " + importCount
+ " bean definitions from URL location [" + location + "]");
}
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error(
"Failed to import bean definitions from URL location [" + location + "]",
ele, ex);
}
} else {
// No URL -> considering resource location as relative to the current file.
// 相對地址則根據地址計算出絕對地址
try {
int importCount;
// Resource存在多個子實現類,如VfsResource、FileSystemResource等,
// 而每個resource的createRelative方式實現都不一樣,
// 所以這裏先使用子類的方法嘗試解析
Resource relativeResource = getReaderContext()
.getResource().createRelative(location);
if (relativeResource.exists()) {
// 遞歸調用bean的解析過程
importCount = getReaderContext()
.getReader().loadBeanDefinitions(relativeResource);
actualResources.add(relativeResource);
} else {
// 如果解析不成功,則使用默認的解析器ResourcePatternResolver進行解析
String baseLocation = getReaderContext()
.getResource().getURL().toString();
// 遞歸調用bean的解析過程
importCount = getReaderContext()
.getReader().loadBeanDefinitions(
StringUtils.applyRelativePath(baseLocation, location),
actualResources);
}
if (logger.isDebugEnabled()) {
logger.debug("Imported " + importCount
+ " bean definitions from relative location ["
+ location + "]");
}
} catch (IOException ex) {
getReaderContext().error(
"Failed to resolve current resource location", ele, ex);
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error(
"Failed to import bean definitions from relative location ["
+ location + "]", ele, ex);
}
}
// 解析後進行監聽器激活處理
Resource[] actResArray = actualResources.toArray(new Resource[0]);
getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}
alias標籤:
聲明方式例如:
<bean id="beanA" class="src.com.BeanA"/>
<alias name="beanA" alias="oneBean,twoBean"/>
還有其他種聲明方式不一一列舉。
protected void processAliasRegistration(Element ele) {
// alias標籤的name屬性值
String name = ele.getAttribute(NAME_ATTRIBUTE);
// alias標籤的alias屬性值
String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
boolean valid = true;
if (!StringUtils.hasText(name)) {
getReaderContext().error("Name must not be empty", ele);
valid = false;
}
if (!StringUtils.hasText(alias)) {
getReaderContext().error("Alias must not be empty", ele);
valid = false;
}
if (valid) {
// name、alias都非空,用bean的name屬性和alias註冊
try {
// getReaderContext().getRegistry()取出來的就是前文的DefaultListableBeanFactory對象,
// 調用SimpleAliasRegistry.java中的registerAlias方法。
getReaderContext().getRegistry().registerAlias(name, alias);
} catch (Exception ex) {
getReaderContext().error("Failed to register alias '" + alias +
"' for bean with name '" + name + "'", ele, ex);
}
// 激活監聽
getReaderContext().fireAliasRegistered(name, alias, extractSource(ele));
}
}
// SimpleAliasRegistry.java registerAlias方法
@Override
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
synchronized (this.aliasMap) {
if (alias.equals(name)) {
// 如果別名和name相同那麼刪除註冊的別名
this.aliasMap.remove(alias);
if (logger.isDebugEnabled()) {
logger.debug(
"Alias definition '" + alias + "' ignored since it points to same name");
}
} else {
String registeredName = this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
return;
}
// SimpleAliasRegistry.java 中的 allowAliasOverriding 方法永遠返回true,
// 意思是允許別名覆蓋,
// 這裏可以用子類覆蓋此方法,返回false不允許別名覆蓋
if (!allowAliasOverriding()) {
throw new IllegalStateException(
"Cannot define alias '" + alias + "' for name '" + name
+ "': It is already registered for name '" + registeredName + "'.");
}
if (logger.isInfoEnabled()) {
logger.info("Overriding alias '" + alias
+ "' definition for registered name '" + registeredName
+ "' with new target name '" + name + "'");
}
}
// 檢查別名是否有循環指向,比如aliasA -> aliasB -> aliasA,
// 如果存在循環指向的話在getBean時候就死循環啦 ~
checkForAliasCircle(name, alias);
// 校驗通過,用ConcurrentHashMap類型的aliasMap保存alias和name的對應關係。
this.aliasMap.put(alias, name);
if (logger.isDebugEnabled()) {
logger.debug("Alias definition '"
+ alias + "' registered for name '" + name + "'");
}
}
}
}
beans標籤:
對前文的doRegisterBeanDefinitions方法的遞歸調用。
bean標籤:重點!!!(超級複雜啊~~~)
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// ④
/*
* 委託BeanDefinitionParserDelegate進行元素解析,
* 返回的bdHolder持有GenericBeanDefinition對象,
* GenericBeanDefinition裝着bean標籤的class、name、id、aliases等屬性值
* 下文詳解此方法,把它標爲 ④
*/
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
/*
* 對默認標籤下的自定義標籤進行解析,比如:
* <bean id="bean" class="test.Bean">
* <myTag:my value="this is value">
* </bean>
* 方法大概實現:遍歷所有屬性,發現需要修飾的屬性時則獲取對應標籤的命名空間,
* 再找到對應的解析器對它進行解析,自定義標籤如何解析在後文分析
*/
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// ⑤
/* 註冊BeanDefinition,也就是把BeanDefinition存到Map裏,把bean的alias也存起來,
* 後文詳細分析此方法,把它標爲 ⑤
* 還記得在AbstractXmlApplicationContext.java 的 loadBeanDefinitions 方法中初始化的
* new XmlBeanDefinitionReader(beanFactory)嗎?
* getReaderContext().getRegistry()取得的
* 就是這個 beanFactory -> DefaultListableBeanFactory,
* 它作爲 Registry 的角色出現了
*/
BeanDefinitionReaderUtils.registerBeanDefinition(
bdHolder, getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
// 發出響應事件,通知相關的監聽器,這個bean已經加載完成了
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
④ parseBeanDefinitionElement 方法詳細分析如下:
// BeanDefinitionParserDelegate.java 的 parseBeanDefinitionElement 方法
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(
Element ele, @Nullable BeanDefinition containingBean) {
// id 屬性
String id = ele.getAttribute(ID_ATTRIBUTE);
// name屬性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// 分割name屬性視爲alias
List<String> aliases = new ArrayList<>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(
nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
// 移除和id相同的的alias
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
// 校驗bean id的唯一性
checkNameUniqueness(beanName, aliases, ele);
}
// 解析bean標籤爲GenericBeanDefinition,標爲 ⑥
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(
ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
// 如果不存在beanName那麼根據Spring中提供的命名規則爲當前bean生成對應的beanName
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
} else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName)
&& beanName.length() > beanClassName.length()
&& !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
} catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
// 將GenericBeanDefinition、beanName、別名列表 放入BeanDefinitionHolder返回
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
⑥ 方法分析如下:
@Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
// 解析class屬性
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
// 解析parent屬性
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 創建 GenericBeanDefinition 類型的 BeanDefinition,用new的方式創建的,代碼就不貼了~
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
/*
* 以下邏輯解析了bean標籤所有屬性封裝在 GenericBeanDefinition 中,解析的代碼很簡單,不貼上來了~~
*/
// 解析 singleton、scope、abstract、lazy-init、autowire、
// depends-on、autowire-candidate、primary、init-method、
// destroy-method、factory-method、factory-bean 屬性存在 BeanDefinition 中
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// 解析 description 屬性
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 解析 meta 屬性以及 key、value,封裝成 BeanMetadataAttribute 存在 BeanDefinition 中
parseMetaElements(ele, bd);
// 解析 lookup-method 屬性以及 name、bean,
// 封裝成 LookupOverride 存在 BeanDefinition 的 MethodOverrides 中
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析 replaced-method 屬性以及 name、replacer、arg-type、match,
// 封裝成 ReplaceOverride 存在 BeanDefinition 的 MethodOverrides 中
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析 constructor-arg 屬性
parseConstructorArgElements(ele, bd);
// 解析 property 屬性
parsePropertyElements(ele, bd);
// 解析 qualifier 屬性
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
} catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
} catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
} catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
} finally {
this.parseState.pop();
}
return null;
}
⑤ BeanDefinitionReaderUtils.registerBeanDefinition 分析:(超級噁心,也是spring核心)
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
// 用beanName註冊BeanDefinition,registry實現類是DefaultListableBeanFactory
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
// 別名拿出來註冊到SimpleAliasRegistry中,前文分析過
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
// DefaultListableBeanFactory.java 的 registerBeanDefinition方法
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) { // true
try {
// 校驗beanDefinition中MethodOverrides對應的方法是否存在
((AbstractBeanDefinition) beanDefinition).validate();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(
beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// DefaultListableBeanFactory 類持有 ConcurrentHashMap 類型的 beanDefinitionMap
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// 處理已經註冊過的beanName
if (existingDefinition != null) {
// 讀取 allowBeanDefinitionOverriding 參數,是否允許beanName重複註冊,這個參數前文講解過,
// 如果不允許則拋出異常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(
beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition
+ "] for bean '" + beanName + "': There is already ["
+ existingDefinition + "] bound.");
} else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION,
// now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isWarnEnabled()) {
logger.warn("Overriding user-defined bean definition for bean '"
+ beanName + "' with a framework-generated bean definition: replacing ["
+ existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName
+ "' with a different definition: replacing [" + existingDefinition
+ "] with [" + beanDefinition + "]");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 覆蓋之前註冊的bean
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
/*
* spring 在 doCreate 方法(後文講)創建 bean 時,
* 每創建一個 bean 就會在 AbstractBeanFactory.java 的
* 成員變量 alreadyCreated(ConcurrentHashMap擴展成的Set類型)內 add 一個 beanName。
*
* 這裏正是判斷 alreadyCreated.isEmpty() 來判斷bean創建過程是否開始的。
*
* spring在創建Bean過程開始後再更改 beanDefinitionNames(ArrayList類型)
* 或 manualSingletonNames(LinkedHashSet類型)
* 都會提前用 hasBeanCreationStarted() 方法判斷一下,
* 之後再對 beanDefinitionMap 加 synchronized 保證操作有序,
* 避免了多線程操作非線程安全集合帶來的問題。
* 這裏用新集合覆蓋原集合的方式更新,而不是在原來的集合上直接操作,
* 我想大概是因爲避免集合的fail-fast異常拋出吧 ~
*/
if (hasBeanCreationStarted()) {
// bean 創建過程已經開始了
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 在beanDefinitionMap中註冊beanName
this.beanDefinitionMap.put(beanName, beanDefinition);
// 記錄beanName
List<String> updatedDefinitions = new ArrayList<>(
this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 刪除手動註冊Singleton記錄的beanName
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(
this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
// Still in startup registration phase
// bean 創建過程尚未開始,仍在啓動註冊階段
// 在beanDefinitionMap中註冊beanName
this.beanDefinitionMap.put(beanName, beanDefinition);
// 記錄beanName
this.beanDefinitionNames.add(beanName);
// 刪除手動註冊Singleton記錄的beanName
this.manualSingletonNames.remove(beanName);
}
// 容器初始化成功後會緩存所有beanDefinition數據,
// 這個數組中的BeanDefinition數據是不會變的,這裏清空了這個緩存的集合。
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
// 如果BeanDefinition已經註冊過,或者已經生成好的Singleton緩存包含這個beanName做重置操作:
// 清除由GenericBeanDefinition轉換成的RootBeanDefinition緩存;
// 銷燬beanName的Singleton緩存;
// 重置beanName對應的BeanDefinition作爲父級的所有BeanDefinition的以上兩種緩存(遞歸)。
resetBeanDefinition(beanName);
}
}
至此,默認標籤已經解析完畢。
自定義標籤解析
回顧一下調用自定義標籤解析的地方:
// DefaultBeanDefinitionDocumentReader.java:
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);
}
}
接下來分析 delegate.parseCustomElement(root);
// BeanDefinitionParserDelegate.java:
@Nullable
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
@Nullable
public BeanDefinition parseCustomElement(
Element ele, @Nullable BeanDefinition containingBd) {
// 取得命名空間uri
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 用 命名空間uri 和 DefaultNamespaceHandlerResolver 解析出 NamespaceHandler
// this.readerContext.getNamespaceHandlerResolver()取得的是
// 前文分析 spring.handlers 時創建的 DefaultNamespaceHandlerResolver
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver()
.resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace ["
+ namespaceUri + "]", ele);
return null;
}
// 調用自定義命名空間處理器解析出BeanDefinition返回
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
// DefaultNamespaceHandlerResolver.java 的 resolve 方法
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// spring.handlers文件配置的命名空間和NamespaceHandler的對應關係集合
Map<String, Object> handlerMappings = getHandlerMappings();
// 用命名空間取得NamespaceHandler實現類
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
} else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
} else {
String className = (String) handlerOrClassName;
try {
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException(
"Class [" + className + "] for namespace [" + namespaceUri
+ "] does not implement the ["
+ NamespaceHandler.class.getName() + "] interface");
}
// 實例化
NamespaceHandler namespaceHandler =
(NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
namespaceHandler.init();
// 用實例化的namespaceHandler覆蓋handlerMappings中String類型的class配置
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
} catch (ClassNotFoundException ex) {
throw new FatalBeanException(
"Could not find NamespaceHandler class [" + className
+"] for namespace [" + namespaceUri + "]", ex);
} catch (LinkageError err) {
throw new FatalBeanException(
"Unresolvable class definition for NamespaceHandler class ["
+ className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
至此 解析及註冊BeanDefinition 步驟已經全部完成 ~~,步驟2 取得了DefaultListableBeanFactory類型的ConfigurableListableBeanFactory,步驟2分析完畢。
步驟3:對BeanFactory進行各種功能填充
先貼上屬性編輯器(PropertyEditor)的帖子:深入分析Spring屬性編輯器(默認屬性編輯器和自定義屬性編輯器) 蟹蟹作者~~
// AbstractApplicationContext.java
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 設置beanFactory的ClassLoader爲當前context的ClassLoader
beanFactory.setBeanClassLoader(getClassLoader());
// 設置beanFactory的表達式語言處理器,Spring3增加了表達式語言的支持,
// 默認可以使用#{bean.xxx}的形式來調用相關屬性值。
beanFactory.setBeanExpressionResolver(
new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 爲beanFactory增加了一個默認的propertyEditor,這個主要是對bean的屬性等設置管理的一個工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
/*
* 添加BeanPostProcessor。
* ApplicationContextAwareProcessor的作用是
* 在bean實例化後,執行initMethod前(執行postProcessBeforeInitialization方法的時機)
* 如果bean實現了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、
* ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware 中的一個或者多個接口,
* 按以上的羅列順序調用各個接口的setxxxx方法,將ApplicationContext中相應屬性設置到bean中。
* 參考文章:https://blog.csdn.net/andy_zhang2007/article/details/86287786
* 感謝作者!~
*/
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
/*
* 設置忽略自動裝配的接口
* 當Spring將ApplicationContextAwareProcessor註冊後,
* 那麼在invokeAwareInterfaces方法中間接調用的Aware類已經不是普通的bean了,
* 如ResourceLoaderAware、ApplicationEventPublisherAware等,
* 那麼當然需要在Spring做bean的依賴注入的時候忽略它們。而ignoreDependencyInterface的作用正是在此。
*/
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
/*
* 註冊幾個自動裝配的特殊規則
* 當註冊了依賴解析後,例如當註冊了對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);
// Register early post-processor for detecting inner beans as ApplicationListeners.
/*
* 添加BeanPostProcessor。
* ApplicationListenerDetector直譯是ApplicationListener探測器,
* 如果bean實現了ApplicationListener接口並且scope是單例,
* 在bean初始化後(執行BeanPostProcessor的postProcessAfterInitialization方法階段)
* 它會被ApplicationListenerDetector捕捉到,
* 作爲ApplicationListeners註冊到容器的事件多播器(ApplicationEventMulticaster)中,
* 在bean銷燬前(執行BeanPostProcessor的postProcessBeforeDestruction方法階段)
* 把bean從應用上下文的事件多播器上移除。
* 參考文章:https://blog.csdn.net/andy_zhang2007/article/details/86374720
* 感謝作者!~
*/
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 增加對AspectJ的支持
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()));
}
// Register default environment beans.
// 添加默認的系統環境bean,將相關環境變量及屬性註冊以單例模式註冊
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());
}
}
步驟5:激活註冊的BeanFactoryPostProcessor處理器
protected void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory) {
/*
* AbstractApplicationContext.java(當前類)持有beanFactoryPostProcessors集合
* 這個集合裝着硬編碼註冊進來的BeanFactoryPostProcessor
* (因爲addBeanFactoryPostProcessor方法沒有人調用呀~~~)
* invokeBeanFactoryPostProcessors(下方法):
* 處理了硬編碼和配置註冊的所有BeanFactoryPostProcessor
*/
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,則增加對AspectJ的支持
if (beanFactory.getTempClassLoader() == null
&& beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(
new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(
new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
// PostProcessorRegistrationDelegate.java:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 如果有 BeanDefinitionRegistryPostProcessors,先調用
Set<String> processedBeans = new HashSet<>();
// beanFactory = DefaultListableBeanFactory, 這裏是 true
// ================ 以下處理 BeanDefinitionRegistryPostProcessor 的實現類 =============
// ====== BeanDefinitionRegistryPostProcessor 繼承自 BeanFactoryPostProcessor =======
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 常規 PostProcessors 集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// registryProcessor 集合
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 傳進來的 beanFactoryPostProcessors 裝着硬編碼註冊的 BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
/*
* 如果實現了 BeanDefinitionRegistryPostProcessor
* (BeanDefinitionRegistryPostProcessor 繼承自 BeanFactoryPostProcessor)
* 要先調用接口方法 postProcessBeanDefinitionRegistry
* 再把它放進 registryProcessors 集合
*/
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 放入 registryProcessor 集合
registryProcessors.add(registryProcessor);
}
else {
/*
* 不然直接放進 常規 PostProcessors 集合
*/
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.
// 不要在這裏初始化FactoryBeans:我們需要保留所有未初始化的常規bean,
// 以使bean工廠後處理器適用於它們!
// 在實現 PriorityOrdered,Ordered 和其餘的 BeanDefinitionRegistryPostProcessors 之間分開。
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先,調用實現 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors。
String[] postProcessorNames =
beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(
beanFactory.getBean(
ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 放入 registryProcessor 集合
registryProcessors.addAll(currentRegistryProcessors);
// 集中調用 BeanDefinitionRegistryPostProcessor 的
// postProcessBeanDefinitionRegistry 方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 接下來,調用實現 Ordered 的 BeanDefinitionRegistryPostProcessors
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)
&& beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(
beanFactory.getBean(
ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 放入 registryProcessor 集合
registryProcessors.addAll(currentRegistryProcessors);
// 集中調用 BeanDefinitionRegistryPostProcessor 的
// postProcessBeanDefinitionRegistry 方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最後,調用所有其他 BeanDefinitionRegistryPostProcessors,
// 直到不再出現其他BeanDefinitionRegistryPostProcessors
// 這裏在不停的在工廠中取得BeanDefinitionRegistryPostProcessor類型的實例,
// 我想應該是在初始化context時,可能發生併發不停的註冊新的Bean,
// 然而不能一直等着其他線程註冊完,那就取到我再也取不到新的爲止吧,繼續往下進行。
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(
beanFactory.getBean(
ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 放入 registryProcessor 集合
registryProcessors.addAll(currentRegistryProcessors);
// 集中調用 BeanDefinitionRegistryPostProcessor 的
// postProcessBeanDefinitionRegistry 方法
invokeBeanDefinitionRegistryPostProcessors(
currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 現在,調用到目前爲止處理的所有處理器的 postProcessBeanFactory 回調
// 先調用 實現了 BeanDefinitionRegistryPostProcessor 接口的
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 再調用普通的
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
// 如果不是 BeanDefinitionRegistry 的實現者,直接調用在上下文實例中註冊的工廠處理器
invokeBeanFactoryPostProcessors(
beanFactoryPostProcessors, beanFactory);
}
// ========= 以下處理 BeanFactoryPostProcessor 的直接實現類 ========
// ====== 和上邊處理 BeanDefinitionRegistryPostProcessor 類似,其實邏輯一毛一樣~~ =======
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(
BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 實現 PriorityOrdered,Ordered 和其餘的 BeanFactoryPostProcessors 之間分開。
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 清除緩存的合併bean定義,因爲後處理器可能已經修改了原始元數據,例如,替換值中的佔位符...
beanFactory.clearMetadataCache();
}
處理順序:
調用硬編碼的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry
調用實現 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors 的 postProcessBeanDefinitionRegistry
調用實現 Ordered 的 BeanDefinitionRegistryPostProcessors 的 postProcessBeanDefinitionRegistry
調用所有其他 BeanDefinitionRegistryPostProcessors 的 postProcessBeanDefinitionRegistry
按上述順序調用實現了 BeanDefinitionRegistryPostProcessor 的 BeanFactoryPostProcessor 的 postProcessBeanFactory
調用硬編碼普通 BeanFactoryPostProcessor 的 postProcessBeanFactory
調用實現 PriorityOrdered 的 BeanFactoryPostProcessor 的 postProcessBeanFactory
調用實現 Ordered 的 BeanFactoryPostProcessor 的 postProcessBeanFactory
調用所有其他 BeanFactoryPostProcessor 的 postProcessBeanFactory
看起來很繁瑣,其實就是按順序調用各種BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor而已。
總結:先BeanDefinitionRegistryPostProcessor,後BeanFactoryPostProcessor。先硬編碼,後配置文件註冊。
BeanFactoryPostProcessor 使用示例:
PropertyPlaceholderConfigurer讀取屬性文件使用詳解
也可以自定義 BeanFactoryPostProcessor 來統一處理 BeanFactory 中的 BeanDefinition,比如統一修改某個屬性值之類的。
步驟6:註冊攔截bean創建的bean處理器
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory,
AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(
BeanPostProcessor.class, true, false);
// 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.
/*
* BeanPostProcessorChecker是一個普通的信息打印,可能會有些情況,
* 當Spring的配置中的後處理器還沒有被註冊就已經開始了bean的初始化時
* 便會打印出BeanPostProcessorChecker中設定的信息
*/
int beanProcessorTargetCount =
beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(
new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 將實現了 PriorityOrdered、 Ordered 和 普通的 BeanPostProcessor 分堆,之後按照順序註冊
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.
// 首先註冊實現了 PriorityOrdered 的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 其次註冊實現了 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.
// 最後,註冊所有 MergedBeanDefinitionPostProcessor 類型的 BeanPostProcessor,
// 並非重複註冊,在 beanFactory.addBeanPostProcessor 中會先移除已經存在的 BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 重新註冊ApplicationListenerDetector
/*
* 添加BeanPostProcessor。
* ApplicationListenerDetector直譯是ApplicationListener探測器,
* 如果bean實現了ApplicationListener接口並且scope是單例,
* 在bean初始化後(執行BeanPostProcessor的postProcessAfterInitialization方法階段)
* 它會被ApplicationListenerDetector捕捉到,
* 作爲ApplicationListeners註冊到容器的事件多播器(ApplicationEventMulticaster)中,
* 在bean銷燬前(執行BeanPostProcessor的postProcessBeforeDestruction方法階段)
* 把bean從應用上下文的事件多播器上移除。
*/
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
步驟7:爲上下文初始化Message源,支持i18n國際化
如何使用:
<!--
MessageSource常見的實現類有
org.Springframework.context.support.ResourceBundleMessageSource
org.Springframework.context.support.ReloadableResourceBundleMessageSource
前者通過資源名加載國際化資源,後者支持定時刷新,可在不重啓系統下更新國際化資源。
-->
<!-- bean id = messageSource 必須寫死 -->
<bean id="messageSource"
class="org.Springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>test/messages</value>
</list>
</property>
</bean>
在test文件夾下定義一組資源文件,比如:messages.property、messages_zh_CN.property
注意資源文件內容需要轉碼。
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
Object[] params = {"Jack", new GregorianCalendar().getTime()};
System.out.println(
"中國:" + context.getMessage("messageKey", params, Locale.CHINA));
System.out.println(
"美國:" + context.getMessage("messageKey", params, Locale.US));
這樣就根據傳入的Locale拿到對應資源文件中messageKey對應的value,傳入參數format進value中輸出出來。
源碼解析:
// AbstractApplicationContext.java
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// MESSAGE_SOURCE_BEAN_NAME = "messageSource" 定義死的,所以配置時需要寫死。
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 如果Factory中有 messageSource,那麼把它拿出來記錄在容器中。
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
// 使父容器也使用同樣的
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
// 如果尚未註冊父MessageSource,則僅將父上下文設置爲父MessageSource。
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
} else {
//如果用戶並沒有定義配置文件,那麼使用臨時的DelegatingMessageSource以便於作爲調用getMessage方法的返回
// Use empty MessageSource to be able to accept getMessage calls.
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 + "]");
}
}
}
// 容器實現了 MessageSource 接口,可以通過容器直接使用MessageSource
@Override
public String getMessage(String code, @Nullable Object[] args,
@Nullable String defaultMessage, Locale locale) {
// getMessageSource() 返回配置的 messageSource
return getMessageSource().getMessage(code, args, defaultMessage, locale);
}
步驟8:初始化應用消息廣播器
ApplicationListener用法:理解 Spring ApplicationListener 感謝作者~~
那麼這裏初始化的就是傳播事件的組件:事件多路廣播器
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
// 註冊自定名爲 applicationEventMulticaster 的 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 + "]");
}
}
}
引用的例子中調用了:
context.publishEvent(event);
publishEvent 方法取得註冊的 applicationEventMulticaster,調用實現的 multicastEvent() 方法來進行多路廣播,也就是循環調用註冊在容器中的 ApplicationListener 實現類,把 ApplicationEvent 傳遞進去,實現事件監聽。
步驟10:查找listener bean,註冊到消息廣播器中
protected void registerListeners() {
// Register statically specified listeners first.
// 首先註冊靜態指定的偵聽器。也就是硬編碼進來的。
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 不要在這初始化bean:我們需要保留所有未經初始化的常規bean,讓後處理器應用於它們!
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) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
步驟11:實例化剩下的單實例(非惰性的)
步驟2讀取了xml文件,生成了BeanDefinition,但是還沒針對這堆BeanDefinition生成單例的實例,現在就來做這件事情。前文在Factory中取bean時候總是調用:
public String[] getBeanNamesForType(
@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit)
方法,取得bean的名字,而沒有取得bean的實例,就是爲了在這統一實例化bean,在實例化bean的過程中調用一些設置好的鉤子函數,統一處理。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 初始化上下文的轉換服務。
// CONVERSION_SERVICE_BEAN_NAME = "conversionService"
// 詳解參見:https://blog.csdn.net/zhuqiuhui/article/details/82316720 感謝作者~
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));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 儘早初始化LoadTimeWeaverAware beans 以允許儘早註冊其變換器。
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 停止使用臨時ClassLoader進行類型匹配。
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 凍結所有的bean定義,說明註冊的bean定義將不被修改或任何進一步的處理。
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 實例化所有剩餘單例(非延遲)。
beanFactory.preInstantiateSingletons();
}
// DefaultListableBeanFactory.java 的 preInstantiateSingletons 方法
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 觸發所有非惰性單例bean的初始化
for (String beanName : beanNames) {
// 用之前解析好的GenericBeanDefinition合併成RootBeanDefinition
// (可能設置了parent屬性,父子bean的情況,做merge操作,用子bean屬性覆蓋父bean屬性)
// getMergedLocalBeanDefinition 方法標註爲 ⑩,後文一同分析
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// FactoryBean的情況
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
// 判斷FactoryBean需不需要提前初始化
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// getBean 執行bean實例化邏輯
getBean(beanName);
}
}
} else {
// getBean 執行bean實例化邏輯
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 觸發所有適用bean的後初始化回調...
// 就是調用所有實現了 SmartInitializingSingleton 接口的bean的 afterSingletonsInstantiated 方法。
for (String beanName : beanNames) {
// getSingleton 標註爲 ⑦ 後文分析
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
到這兒程序回到 DefaultListableBeanFactory,getBean 方法爲 BeanFactory 核心。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
BeanFactory 提供了幾種getBean重載方法,都會調用 doGetBean 方法,doGetBean爲核心。
這裏需要了解 FactoryBean 是怎麼用的,推薦文章: 一分鐘瞭解spring之FactoryBean
也需要簡單瞭解下java安全管理器SecurityManager 、Spring中depends-on的作用是什麼?
感謝作者!~
// AbstractBeanFactory.java
protected <T> T doGetBean(
final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// transformedBeanName 做了兩件事:
// 1、刪除工廠方法的&前綴(如果有)
// 2、如果是 alias,則轉換成真實的 beanName
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 積極地嘗試從緩存中獲取單例bean,可能拿不到bean
/*
* bean沒在緩存中並且bean也不在創建中(需要從頭執行創建流程),返回null
* 或 beanName對應的bean根本不存在,返回null
* 或 bean正在創建中,但spring還沒構建好 ObjectFactory,返回null
* 後文還會調用此方法,getSingleton 標註爲 ⑦
*/
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// 取到了實例
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
// 打出bean還未完全初始化好的log,
// 因爲有循環引用存在,Factory沒處理完就先返回了bean實例
logger.debug("Returning eagerly cached instance of singleton bean '"
+ beanName
+ "' that is not fully initialized yet - a consequence of a circular reference");
} else {
// log:返回了緩存的實例
// 程序走到這裏,bean應該是初始化完成了的,
// 只不過在getSingleton時拿到的是創建過程中緩存的bean,
// 通過 isSingletonCurrentlyInCreation 的判斷,現在應該是處理完了。
logger.debug("Returning cached instance of singleton bean '"
+ beanName + "'");
}
}
// 獲取給定bean實例的對象,bean實例本身或其創建的對象(如果是 FactoryBean)。
// getObjectForBeanInstance 標註爲 ⑧
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
// 如果原型(prototype)bean在當前線程正在創建中,拋出異常。
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 檢查此工廠中是否存在bean定義。
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 當前BeanFactory沒有beanName的BeanDefinition,檢查父BeanFactory
// Not found -> check parent.
// 確定原始bean名稱,將本地定義的別名解析爲規範名稱。
// originalBeanName方法 比 transformedBeanName 多做了一件事:
// 如果name以"&"開頭,將轉化後的標準名稱加上"&"前綴
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 在父工廠取得bean
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
// Delegation to parent with explicit args.
// 使用顯式args委託父級。
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else {
// No args -> delegate to standard getBean method.
// 沒有args -> 委託給標準的getBean方法。
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// 刪除名爲 beanName 的 mergedBeanDefinition緩存
// 讓bean定義重新合併,以防萬一其中一些元數據在此期間發生變化。
// 添加 alreadyCreated 標記
// markBeanAsCreated 標註爲 ⑨
markBeanAsCreated(beanName);
}
try {
// 重新合併BeanDefinition
// getMergedLocalBeanDefinition 標註爲 ⑩
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 校驗是否是抽象類,是的話拋出異常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 保證當前bean依賴的bean的初始化。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
// 循環依賴的情況報錯
throw new BeanCreationException(mbd.getResourceDescription(),
beanName,
"Circular depends-on relationship between '"
+ beanName + "' and '" + dep + "'");
}
// 記錄依賴關係
registerDependentBean(dep, beanName);
try {
// 先初始化依賴的bean,遞歸getBean
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(),
beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 創建bean實例
if (mbd.isSingleton()) {
// Singleton 的情況
// 創建一個 ObjectFactory 隱藏實際創建bean的細節
// getSingleton 標註爲 ⑪
sharedInstance = getSingleton(beanName, () -> {
try {
// createBean 標註爲 ⑫
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
// 從單例緩存中顯式刪除實例:它可能已經被創建過程急切地放在那裏,以允許循環引用解析。
// 也刪除任何接收到bean的臨時引用的bean。
destroySingleton(beanName);
throw ex;
}
});
// 獲取給定bean實例的對象,bean實例本身或其創建的對象(如果是 FactoryBean)。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// Prototype 的情況
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 記錄當前線程正在創建的 beanName
beforePrototypeCreation(beanName);
// 同上 createBean 標註爲 ⑫
prototypeInstance = createBean(beanName, mbd, args);
} finally {
// 移除當前線程正在創建的 beanName
afterPrototypeCreation(beanName);
}
// 獲取給定bean實例的對象,bean實例本身或其創建的對象(如果是 FactoryBean)。
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 非單例非原型 的情況
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
// 沒找到Scope報錯
throw new IllegalStateException(
"No Scope registered for scope name '" + scopeName + "'");
}
try {
// 由註冊進來的Scope來保證bean的範圍
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
// 獲取給定bean實例的對象,bean實例本身或其創建的對象(如果是 FactoryBean)。
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName
+ "' is not active for the current thread; consider "
+ "defining a scoped proxy for this bean if you intend to"
+ " refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
// 清除 alreadyCreated 標記
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 檢查所需類型是否與實際bean實例的類型匹配。
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
先分析 ⑨ markBeanAsCreated 方法:
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
synchronized (this.mergedBeanDefinitions) {
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 現在我們實際創建bean了,讓bean定義重新合併...... 以防萬一其中一些元數據在此期間發生變化。
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
⑦ getSingleton(String beanName)方法:
getSingleton(String beanName) 提取試着提取單例實例,或者調用構建好的ObjectFactory獲取實例
// DefaultSingletonBeanRegistry.java
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 如果沒有拿到,並且這個bean還正在創建中...
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// DefaultSingletonBeanRegistry類 singletonObjects 屬性
// 持有所有已經實例化的singleton集合(ConcurrentHashMap)
synchronized (this.singletonObjects) {
/*
* 在創建bean過程中,有自動注入的情況:
* 比如 A->B->C->A...,
* A類包含一個B類的屬性,可是容器中B類還沒有被實例化,
* 實例化A後(通過構建好的 ObjectFactory),將A實例放入 earlySingletonObjects,
* 去實例化B,將B實例放入 earlySingletonObjects,再去實例化C,
* 實例化C後發現C類包含有A類屬性,那就直接從 earlySingletonObjects取得A就好了,
* 這樣拿到的A實例就能保證是同一個。
* 解決了循環依賴問題。
*
* ObjectFactory 隱藏了bean的創建細節,在工廠中可能存在對bean的增強(AOP),
* 如果需要AOP則返回AOP後的代理實例,如果無AOP直接返回bean本身實例
*/
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 創建實例時會把實際創建過程隱藏在 ObjectFactory 中(程序主線不關心具體bean創建過程)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 創建實例
singletonObject = singletonFactory.getObject();
// 記錄在緩存中,earlySingletonObjects 和 singletonFactories 互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
⑧ getObjectForBeanInstance 方法:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
/*
* 有以下幾種情況:
* Ⅰ: beanName = "a" A instanceof FactoryBean = true return A FactoryBean創建的實例
* Ⅱ: beanName = "a" A instanceof FactoryBean = false return A的單例實例
* Ⅲ: beanName = "&a" A instanceof FactoryBean = true return A FactoryBean
* Ⅳ: beanName = "&a" A instanceof FactoryBean = false return 報錯
*/
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 對 FactoryBean 進行特殊情況處理和校驗
// isFactoryDereference 方法檢查 name 是否以"&"開頭
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果name帶"&"說明是FactoryBean,但是剛拿到的beanInstance不是個工廠,拋出異常,情況Ⅳ
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 現在我們有了bean實例,它可能是 普通bean 或 FactoryBean。
// 如果它是FactoryBean,我們使用它來創建bean實例,除非調用者實際上想要引用工廠。
if (!(beanInstance instanceof FactoryBean)
|| BeanFactoryUtils.isFactoryDereference(name)) {
// 情況Ⅱ、情況Ⅲ
return beanInstance;
}
// 情況Ⅰ: 通過FactoryBean創建實例
Object object = null;
if (mbd == null) { // true
// 從 FactoryBeans創建的單例對象緩存 中取得Bean實例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
// 從工廠返回bean實例
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 緩存從FactoryBean獲取的對象(如果它是單例)。
if (mbd == null && containsBeanDefinition(beanName)) {
// 獲取合併後的BeanDefinition
// getMergedLocalBeanDefinition 方法標註爲 ⑩
mbd = getMergedLocalBeanDefinition(beanName);
}
// 判斷是否是合併的BeanDefinition,比如父子bean的情況
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 從 FactoryBean 獲取實例,合併bean不執行PostProcess
// getObjectFromFactoryBean 方法標註爲 ⑬
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
⑩ getMergedLocalBeanDefinition 方法:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName)
throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// 首先快速檢查併發映射,鎖定最小。
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
// 設置了parent屬性具有父子bean的情況
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
// 轉換bean名稱,刪除工廠前綴,並將別名解析爲規範名稱。
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 遞歸取得父類的MergedBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
} else {
// beanName 和 父beanName 重名的情況,嘗試在父工廠尋找父類的MergedBeanDefinition
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// 深度拷貝
mbd = new RootBeanDefinition(pbd);
// 用子的屬性覆蓋父的屬性
mbd.overrideFrom(bd);
}
// Set default singleton scope, if not configured before.
// 如果未配置scope屬性,則設置默認單例。
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// 包含在非單例bean中的bean本身不能是單例。
// 讓我們在這裏動態更正,因爲這可能是外部bean的父子合併的結果,
// 在這種情況下,原始內部bean定義將不會繼承合併的外部bean的單例狀態。
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// 暫時緩存合併的bean定義(稍後可能仍會重新合併以獲取元數據更改)
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
⑬ getObjectFromFactoryBean 方法:
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 配置的FactoryBean是單例 並且 緩存已經存在beanName對應的單例
if (factory.isSingleton() && containsSingleton(beanName)) {
// 鎖定 singletonObjects
synchronized (getSingletonMutex()) {
// 從 FactoryBeans創建的單例對象的緩存 中嘗試取得
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 從給定FactoryBean中獲取對象,也就是FactoryBean.getObject()
// doGetObjectFromFactoryBean 標註爲 ⑭
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
// 只有在上面的getObject()調用期間沒有進行後處理和存儲(例如,由於自定義getBean調用觸發的循環引用處理)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
} else {
// 非合併bean需要執行 PostProcess
if (shouldPostProcess) {
/*
* 此處判斷bean是否在創建中的邏輯應該是爲了避免遞歸調用死循環的情況。
* 用 singletonObjects 加鎖,當前線程可以重入!
* 防止 BeanPostProcessor 的 postProcessAfterInitialization() 方法
* 再次以 beanName 從工廠中獲取bean,進而再次執行 postProcessAfterInitialization() 導致死循環。
* 重入後不再執行 postProcessAfterInitialization,直接返回 object。
*/
// 判斷單例bean當前是否正在創建
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
// 暫時返回沒調用後處理的對象,而不是存儲它。
return object;
}
// 添加正在創建狀態
beforeSingletonCreation(beanName);
try {
// 執行 BeanPostProcessor 的 postProcessAfterInitialization
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
} finally {
// 解除正在創建狀態
afterSingletonCreation(beanName);
}
}
// 如果容器緩存了單例,那麼把創建的實例也放進 FactoryBeans創建的單例對象的緩存
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
} else {
// 從給定FactoryBean中獲取對象,也就是FactoryBean.getObject()
// doGetObjectFromFactoryBean 標註爲 ⑭
Object object = doGetObjectFromFactoryBean(factory, beanName);
// 非合併bean需要執行PostProcess
if (shouldPostProcess) {
try {
// 執行 BeanPostProcessor 的 postProcessAfterInitialization
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
// AbstractAutowireCapableBeanFactory.java 的 postProcessObjectFromFactoryBean 方法
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
⑭ doGetObjectFromFactoryBean 方法,它主要功能就是執行factory.getBean(),調用工廠生成實例:
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
// FactoryBean.getObject() 返回實例
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);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
// 不接受尚未完全初始化的FactoryBean的空值:許多FactoryBeans只返回null。
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
回過頭分析 doGetBean 方法中 的:
⑪ getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 嘗試在單例對象的緩存中獲取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// singletonsCurrentlyInDestruction = false; 優雅關閉Context刪除緩存的單例時會修改爲true
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 添加當前bean正在創建中狀態
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 調用工廠,返回新實例
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 刪除正在創建狀態
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 添加單例bean的緩存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
⑫ createBean 方法
doGetBean 調用 ⑪ 時構建了一個 ObjectFactory,這個ObjectFactory很簡單,單純的調用⑫ createBean 方法
// AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 確保此時實際解析了bean的class,並且在動態解析的類的情況下克隆beanDefinition,
// 該克隆對象不能存儲在共享的合併bean定義中。
// 鎖定class,根據設置的class屬性或者根據className來解析Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 準備方法覆蓋, lookup-method 或 replace-method 的情況
try {
// 驗證及準備覆蓋的方法
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 給BeanPostProcessors一個機會來返回代理來替代真正的實例
// resolveBeforeInstantiation 標註爲 ⑮
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 當經過前置處理後返回的結果如果不爲空,那麼會直接略過後續的bean的創建而直接返回結果。
// AOP功能就是基於這裏判斷的。
if (bean != null) {
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 創建指定的bean
// doCreateBean 標註爲 ⑯
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
⑮ resolveBeforeInstantiation 方法:
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 確保此時實際解析了bean class。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 確定給定bean定義的目標類型。
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/*
* 執行所有 InstantiationAwareBeanPostProcessor 類型的
* BeanPostProcessor 的 postProcessBeforeInstantiation() 方法
*
* 執行這個方法後,bean或許成爲了一個經過處理的代理bean,
* 可能是通過cglib生成的,也可能是通過其他技術生成的。
*/
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
/*
* 如果postProcessBeforeInstantiation返回的結果不是null!!!!
* 說明 InstantiationAwareBeanPostProcessor 可能對bean做了實例化處理
* 而不再doCreatBean生成實例,直接返回bean。
* 在返回bean前,儘可能地保證註冊的 BeanPostProcessor 的
* postProcessAfterInitialization() 方法可以執行。
*/
/*
* 執行所有 BeanPostProcessor 的 postProcessAfterInitialization() 方法
*/
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(
Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(
Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
⑯ doCreateBean 方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 實例化bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 從 未完成的FactoryBean實例的緩存 取得instanceWrapper
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 使用適當的實例化策略爲指定的bean創建新實例:factory方法、構造函數自動裝配或簡單實例化。
// createBeanInstance 標註爲 ⑰
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 允許後處理器修改合併的bean定義。
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 執行 MergedBeanDefinitionPostProcessor類型的 BeanPostProcessor 的 postProcessMergedBeanDefinition() 方法
// 主要是尋找幾個註解,@PostConstruct, @Autowire, @Value, @Resource,@PreDestroy 等
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 提前緩存單例以便能夠解析循環引用,甚至在由BeanFactoryAware等生命週期接口觸發時也是如此。
/*
* 是否需要提早曝光:當前bean是單例 && 允許循環依賴 && 當前bean正在創建中,檢測循環依賴
* allowCircularReferences 可以通過硬編碼方式設置進去:
* classPathXmlApplicationContext.setAllowBeanDefinitionOverriding(false);
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
// 提早緩存 bean:beanName 允許解決潛在的循環引用
}
// 爲避免後期循環依賴,可以在bean初始化完成前將創建實例的 ObjectFactory 加入單例工廠集合
// 這樣後期如果有其他bean依賴該bean,可以從singletonFactories獲取到bean。
// getEarlyBeanReference() 調用 SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference()方法
// 其中我們熟知的AOP就是在這裏將advice動態織入bean中,若沒有則直接返回bean,不做任何處理
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 初始化bean實例。
Object exposedObject = bean;
try {
// 對bean進行填充,將各個屬性值注入,其中,可能存在依賴於其他bean的屬性,則會遞歸初始依賴bean
// populateBean 標註爲 ⑱
populateBean(beanName, mbd, instanceWrapper);
// 調用初始化方法,比如init-method
// initializeBean 標註爲 ⑲
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);
}
}
// 如果 earlySingletonExposure,嘗試從緩存獲取該bean
// (一般存放在 singletonFactories 對象通過調用 getObject 把對象存入 earlySingletonObjects),
// 分別從 singletonObjects 和 earlySingletonObjects 獲取對象
if (earlySingletonExposure) {
// ⑦ 的 getSingleton
Object earlySingletonReference = getSingleton(beanName, false);
// earlySingletonReference 只有在檢測到有循環依賴的情況下才會不爲空
if (earlySingletonReference != null) {
// 如果 exposedObject 沒有在初始化方法中被改變,也就是沒有被增強
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 檢測依賴
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/*
* 因爲bean創建後其所依賴的bean一定是已經創建的,
* actualDependentBeans 不爲空 則表示當前bean創建後其依賴的bean卻沒有全部創建完,
* 也就是說存在循環依賴.
*/
if (!actualDependentBeans.isEmpty()) {
// 拋出Bean目前正在創建中異常
// 名爲 beanName 的Bean已經作爲循環引用的一部分注入其原始版本的其他bean [...],但最終被包裝。
// 這意味着所述其他bean不使用bean的最終版本。
// 這通常是過於急切類型匹配的結果 - 例如,考慮使用'getBeanNamesOfType'並關閉'allowEagerInit'標誌。
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
// 將bean註冊爲一次性。
try {
// 註冊DisposableBean接口,在工廠關閉時調用的給定destroy方法。
// registerDisposableBeanIfNecessary 標註爲 ⑳
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
protected void applyMergedBeanDefinitionPostProcessors(
RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
protected void addSingletonFactory(
String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
protected Object getEarlyBeanReference(
String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
doCreateBean 調用的 ⑰ createBeanInstance:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 確保此時實際解析了bean class。
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 非public類且無public的構造方法標識類不允許被訪問,拋出異常
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// Support for functional instance supplier callback at BeanDefinition level
// 用supplier方式生成實例
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工廠方法不爲空則使用工廠方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 一個類有多個構造函數,每個構造函數都有不同的參數,
// 所以調用前需要先根據參數鎖定構造函數或對應的工廠方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已經解析過則使用解析好的構造函數方法不需要再次鎖定
if (resolved) {
if (autowireNecessary) {
// 構造函數自動注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 使用默認構造函數構造
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 需要根據參數解析構造函數
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 構造函數自動注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
// 沒有特殊處理:只需使用no-arg構造函數。
return instantiateBean(beanName, mbd);
}
doCreateBean 調用的 ⑱ populateBean:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
// 如果實例爲null,但還有屬性,拋出異常
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
// Skip property population phase for null instance.
// 跳過null實例的屬性填充階段。
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 給InstantiationAwareBeanPostProcessors最後一次機會在屬性設置前來改變bean
// 如:可以用來支持屬性注入的類型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值爲是否繼續填充bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果後處理器發出停止填充命令則終止後續的執行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 如果該bean是支持按照名字或者類型自動注入的,
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
// 深度拷貝PropertyValues,當然對於對象來說只能公用一個
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根據名稱自動注入(byName),統一存入PropertyValues中
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根據類型自動注入(byType),統一存入PropertyValues中
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 後處理器已經初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 需要依賴檢查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 對所有需要依賴檢查的屬性進行後處理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依賴檢查,對應depends-on屬性,3.0已經棄用此屬性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 將屬性應用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 尋找bw中需要依賴注入的屬性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 遞歸初始化相關bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 註冊依賴
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");
}
}
}
}
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
//尋找bw中需要依賴注入的屬性
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
// 探測指定屬性的set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 解析指定beanName的屬性所匹配的值,並把解析到的屬性名稱存儲在
// autowiredBeanNames中,當屬性存在多個封裝bean時如:
// @Autowired private List<A> aList;將會找到所有匹配A類型的bean並將其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
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 + "'");
}
}
autowiredBeanNames.clear();
}
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
doCreateBean 調用的 ⑲ initializeBean:
方法中4個步驟極爲重要:
- 對特殊的bean處理:Aware、BeanClassLoaderAware、BeanFactoryAware
- 調用 BeanPostProcessor 的 postProcessBeforeInitialization() 方法
- 激活用戶自定義的init方法
- 調用 BeanPostProcessor 的 postProcessAfterInitialization() 方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 對特殊的bean處理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 應用後處理器,調用 BeanPostProcessor 的 postProcessBeforeInitialization() 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 激活用戶自定義的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 後處理器應用,調用 BeanPostProcessor 的 postProcessAfterInitialization() 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 首先會檢查是否是InitializingBean,如果是的話需要調用afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
// 屬性初始化後的處理
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 調用自定義初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
doCreateBean 調用的 ⑳ registerDisposableBeanIfNecessary:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
// 註冊一個執行所有銷燬的DisposableBean實現爲給定的bean工作:DestructionAwareBeanPostProcessors,
// DisposableBean接口,自定義銷燬方法。
/*
* 單例模式下注冊需要銷燬的bean,此方法中會處理實現DisposableBean的bean,
* 並且對所有的bean使用DestructionAwareBeanPostProcessors處理
* DisposableBeanDestructionAwareBeanPostProcessors
*/
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
} else {
// A bean with a custom scope...
// 具有自定義範圍的bean ...
// 自定義scope的處理
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
步驟12:完成刷新過程
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 清除上下文級資源緩存(例如來自掃描的ASM元數據)。
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 爲此上下文初始化生命週期處理器。
// 當ApplicationContext啓動或停止時,它會通過LifecycleProcessor來與所有聲明的bean的週期做狀態更新,
// 而在LifecycleProcessor的使用前首先需要初始化。
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
// 首先將刷新傳播到生命週期處理器。
// 啓動所有實現了Lifecycle接口的bean。
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 當完成ApplicationContext初始化的時候,要通過Spring中的事件發佈機制來發出ContextRefreshedEvent事件,
// 以保證對應的監聽器可以做進一步的邏輯處理。
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
// 向MBeanServer註冊LiveBeansView,可以通過JMX來監控此ApplicationContext。
LiveBeansView.registerApplicationContext(this);
}
終於寫完了…