Spring源碼閱讀之bean對象的創建過程
Spring是通過IOC容器來管理對象的,該容器不僅僅只是幫我們創建了對象那麼簡單,它負責了對象的整個生命週期-創建、裝配、銷燬。這種方式成爲控制反轉(組件對象控制權的轉移,從程序代碼本身轉移到了外部容器,容器創建完對象後注入組件中)。
Spring的核心的是容器,不過這個容器並不是唯一的,框架本身就提供了很多個容器的實現,大概分爲兩種類型:
- BeanFactory:最簡單的容器,只能提供基本的DI(依賴注入)功能。
- ApplicationContext(應用上下文):繼承自BeanFactory,它能提供更多企業級的服務,例如解析配置文本信息等等,這也是ApplicationContext實例對象最常見的應用場景。
簡單說說這兩種方式的區別:
- 原始的BeanFactory無法支持spring的許多插件,如AOP功能、Web應用
- ApplicationContext利用MessageSource進行國際化 並有着事件機制。
- ApplicationContext擴展了ResourceLoader(資源加載器)接口,從而可以用來加載多個Resource,而BeanFactory是沒有擴展ResourceLoader
- 與BeanFactory通常以編程的方式被創建不同的是,ApplicationContext能以聲明的方式創建,如使用ContextLoader。當然你也可以使用ApplicationContext的實現之一來以編程的方式創建ApplicationContext實例 。
- BeanFactroy採用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調用getBean()),纔對該Bean進行加載實例化,這樣,我們就不能發現一些存在的spring的配置問題。而ApplicationContext則相反,它是在容器啓動時,一次性創建了所有的Bean。這樣,在容器啓動時,我們就可以發現Spring中存在的配置錯誤。
ApplicationContext 介紹
如果說BeanFactory是Sping的心臟,那麼ApplicationContext就是完整的身軀了。ApplicationContext由BeanFactory派生而來,提供了更多面向實際應用的功能。在Beanfactory中,很多功能需要以編程的方式實現,而在ApplicationContext中則可以通過配置的方式實現。
ApplicationContext類體系結構:
在上一篇源碼閱讀WebContextApplication初始化中說到實際創建的對象爲XmlWebApplicationContext
,該類繼承了AbstractRefreshableWebApplicationContext
(上圖的左下角),也是ApplicationContext體系。那麼該對象讀取配置文件後是如何創建bean對象的呢?
大致分爲兩步:
-
實例化BeanDefinition對象(下面分析該對象的作用) 。
-
實例化bean對象。
1. 實例化BeanDefinition對象
WebContextApplication初始化說到初始化的步驟是在ContextLoader
中完成,創建完XmlWebApplicationContext
對象後,通過configureAndRefreshWebApplicationContext()
設置配置文件的位置。
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
String configLocationParam;
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
configLocationParam = sc.getInitParameter("contextId");
if (configLocationParam != null) {
wac.setId(configLocationParam);
} else {
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath()));
}
}
//設置ServletContext環境。
wac.setServletContext(sc);
/*讀取Servlet對象中的contextConfigLocation. ServletContext在創建的時候就讀取了
<context-param>標籤,並將該標籤中的配置文件的信息通過鍵值對的形式保存進來了。
*/
configLocationParam = sc.getInitParameter("contextConfigLocation");
if (configLocationParam != null) {
//保存配置文件信息的位置。
wac.setConfigLocation(configLocationParam);
}
//刷新環境
wac.refresh();
}
配置文件位置設置完成後就需要讀取該文件的配置信息,並創建相應的bean對象,這一過程就是在refresh()
中完成的。
通過圖中的繼承關係往上尋找在AbstractApplicationContext
中發現·refresh
方法,
該方法進行一些初始化操作。
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
// 1.刷新前的預處理,包含設置啓動時間、設置狀態...
this.prepareRefresh();
//實現刷新BeanFactory,將配置文件解析爲BeanDefinition並註冊到BeanFactory,此時Bean還未被初始化
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// BeanFactory的預準備工作
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
// 執行BeanFactoryPostProcessor的方法,BeanFactory的後置處理器
// 在BeanFactory標準初始化之後執行的
this.invokeBeanFactoryPostProcessors(beanFactory);
// 註冊BeanPostProcessor(Bean的後置處理器),用於攔截bean創建過程
this.registerBeanPostProcessors(beanFactory);
// 初始化MessageSource組件(做國際化功能;消息綁定,消息解析).
this.initMessageSource();
// 初始化上下文的事件機制
this.initApplicationEventMulticaster();
// 可以用於子類實現在容器刷新時自定義邏輯初始化
this.onRefresh();
// 註冊時間監聽器,將ApplicationListener註冊到容器中來
this.registerListeners();
// 初始化所有剩下的單實例bean,單例bean在初始化容器時創建。
this.finishBeanFactoryInitialization(beanFactory);
// 發佈完成事件,結束初始化過程
this.finishRefresh();
} catch (BeansException var5) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var5);
this.destroyBeans();
this.cancelRefresh(var5);
throw var5;
}
}
}
obtainFreshBeanFactory
將配置文件解析爲BeanDefinition並註冊到BeanFactory中
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 主要是通過該方法完成IoC容器的刷新
this.refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
refreshBeanFactory
完成IOC容器的刷新,具體實現是在AbstractRefreshableApplicationContext
中,實際創建的的IOC容器爲:DefaultListableBeanFactory
protected final void refreshBeanFactory() throws BeansException {
//首先檢查是否已經有beanFactory了,有就銷燬
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
// 創建IoC容器,也就是DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
this.customizeBeanFactory(beanFactory);
//載入剛創建的IOC容器,具體實現在子類XmlWebApplicationCpntext中
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
loadBeanDefinitions
裝載剛創建的IOC容器,具體實現在XmlWebApplicationCpntext
中。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 創建一個BeanDefinition閱讀器,通過閱讀XML文件,真正完成BeanDefinition的加載和註冊
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//beanDefinitionReaderde 初始化操作
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
this.loadBeanDefinitions(beanDefinitionReader);
}
//方法重載
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
/*在上一篇文章中ContextLoader中的configureAndRefreshWebApplicationContext方法有這一段代碼
configLocationParam = sc.getInitParameter("contextConfigLocation");
if (configLocationParam != null) {
//保存配置文件信息的位置。
wac.setConfigLocation(configLocationParam);
}
這裏就是讀取配置文件的信息,保存進數組中。
*/
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
String[] var3 = configLocations;
int var4 = configLocations.length;
for(int var5 = 0; var5 < var4; ++var5) {
String configLocation = var3[var5];
//具體的裝載方法在XmlBeanDefinitionReader
reader.loadBeanDefinitions(configLocation);
}
}
}
接下來看XmlBeanDefinitionReader
中的loadBeanDefinitions()
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 對配置文件進行編碼處理
return this.loadBeanDefinitions(new EncodedResource(resource));
}
//截取主要代碼
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
try {
//將配置文件轉換成流對象
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
// 從InputStream中得到XML的解析源
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 這裏是具體的讀取過程,var5等於新註冊的BeanDefintion數量
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
}
具體的讀取過程在doLoadBeanDefinitions()
中,該方法的主要作用就是:
- 一個是對XML文件進行DOM解析
- 一個是完成BeanDefinition對象的加載與註冊
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
//把資源文件轉換成Document對象
Document doc = this.doLoadDocument(inputSource, resource);
// 通過對Document對象的操作,完成BeanDefinition的加載和註冊工作
return this.registerBeanDefinitions(doc, resource);
}Catch(){
}
}
看看registerBeanDefinitions()
具體完成了哪些操作:
- 創建DefaultBeanDefinitionDocumentReader用來解析Document對象。
- 獲得容器中已註冊的BeanDefinition數量
- 委託給DefaultBeanDefinitionDocumentReader來完成BeanDefinition的加載、註冊工作。
- 統計新註冊的BeanDefinition數量
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 1.
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
documentReader.setEnvironment(this.getEnvironment());
// 2.
int countBefore = this.getRegistry().getBeanDefinitionCount();
// 3. 解析過程入口,BeanDefinitionDocumentReader只是個接口,具體的實現過程在DefaultBeanDefinitionDocumentReader完成
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
// 4.
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
接着看DefaultBeanDefinitionDocumentReader
中的registerBeanDefinitions()
該方法:
- 獲得Document的根元素標籤
- 真正實現BeanDefinition解析和註冊工作
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.logger.debug("Loading bean definitions");
//獲取文檔對象的子節點。
Element root = doc.getDocumentElement();
//真正的解析註冊方法
this.doRegisterBeanDefinitions(root);
}
到這一步接下來就是對解析文檔中的每一個標籤節點,獲取標籤中的屬性。創建AbstractBeanDefinition
對象,並將標籤中屬性保存進對象中。具體的步驟就不展示了。
綜上步驟具體完成了以下操作:
-
創建IoC容器(DefaultListableBeanFactory)
-
加載解析XML文件(最終存儲到Document對象中)
-
讀取Document對象,並完成BeanDefinition的加載和註冊工作
BeanDefinition 在 spring 中貫穿始終,spring 要根據 BeanDefinition 對象來實
例化 bean,只有把解析的標籤,掃描的註解類封裝成 BeanDefinition 對象,spring
**才能實例化 bean **
上面的步驟只是完成了AbstractApplicationContext中refresh()
這句話(心累…)
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
2. 實例化Bean對象
進入AbstractApplicationContext
中的finishBeanFactoryInitialization()
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
// 實例化剩餘的單例bean(非懶加載方式)
// 注意事項:Bean的IoC、DI和AOP都是發生在此步驟
beanFactory.preInstantiateSingletons();
}
進入DefaultListableBeanFactory中的preInstantiateSingletons()方法:
- 通過beanName獲取bean實例,如果獲取到的實例不滿足條件就看最後一行getBean(beanName);
- 核心代碼 getBean(beanName);
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// 得到Bean定義名稱
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 觸發所有非懶加載方式的單例bean的創建
for (String beanName : beanNames) {
// 遍歷得到對應的bean定義信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 如果bean不是抽象的,而且是單例的,同時還不是懶加載的,則進行下面的操作
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果bean是一個工廠bean,則走下面的方法 ,和普通bean區別就是還可以生成bean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
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(beanName);
}
}
}
else { // 普通bean走下面的方法
getBean(beanName);
}
}
}
進入AbstractBeanFactory通過doGetBean()方法獲取Bean的實例(只展示關鍵代碼)
-
通過getSingleton(beanName)方法去緩存中獲取單例Bean(第一次初始化,緩存中不存在)
-
如果取出來的bean實例是factoryBean的實例,則需要從factoryBean中產生一個Bean對象
-
根據當前的beanfactory獲取父一級的beanFactory,遞歸查找我們需要的Bean(Bean是早不到的,第一次初始化)
-
獲取實例化Bean的BeanDefinition對象
-
一般是單例Bean,用匿名內部類的寫法,創建單例Bean
@Override public Object getBean(String name) throws BeansException { // 獲取Bean的實例 return doGetBean(name, null, null, false); } @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 獲取bean名稱 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 從緩存中獲取單例bean Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //如果獲取到單例bean,則走下面代碼 if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } // 如果取出來的Bean實例是FactoryBean的Bean實例,則需要從FactoryBean實例中產生一個對象實例。 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else {//如果沒有獲取到單例bean,則走下面代碼 try { // 獲取要實例化的bean的BeanDefinition對象 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 檢查該BeanDefinition對象對應的Bean是否是抽象的 checkMergedBeanDefinition(mbd, beanName, args); // 如果是單例的Bean,請下面的代碼 if (mbd.isSingleton()) { //匿名內部類的寫法 sharedInstance = getSingleton(beanName, () -> { try { // 創建單例Bean的主要方法 return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } return (T) bean; }
進一步看看
createBean()
具體實現在AbstractAutowireCapableBeanFactory
中@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //省略一些代碼 try { // 完成Bean實例的創建(實例化、填充屬性、初始化) Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } ****
doCreateBean完成Bean實例的創建(實例化、填充屬性、初始化)
- bean初始化第一步,默認調用無參數構造實例化bean
- bean初始化第二步,填充屬性(DI依賴注入發生在此步驟)
- bean初始化第三步,調用初始化方法,完成bean的初始化操作AOP發生在此步驟)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. // 用BeanWrapper來持有創建出來的Bean對象 BeanWrapper instanceWrapper = null; // 如果是單例的話,則先把緩存中的bean清除 if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // bean初始化第一步:默認調用無參構造實例化Bean // 構造參數依賴注入,就是發生在這一步 // 爲了下一步populateBean方法的屬性注入做準備 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } // 實例化後的Bean對象 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. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { 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. // 解決循環依賴的關鍵步驟 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); // 如果需要提前暴露單例Bean,則將該Bean放入三級緩存中 if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 將剛創建的bean放入三級緩存中singleFactories(key是beanName,value是FactoryBean) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { // bean初始化第二步:填充屬性(DI依賴注入發生在此步驟) populateBean(beanName, mbd, instanceWrapper); // bean初始化第三步:調用初始化方法,完成bean的初始化操作(AOP發生在此步驟) exposedObject = initializeBean(beanName, exposedObject, mbd); } ****************************************** }
進入上面的initializeBean()方法:
- 應用BeanPostProcessor的postProcessBeforeInitialization方法在初始化之前被調用
- 執行初始化方法(先調用InitializingBean的afterPropertiesSet,再調用init-method屬性指定的初始化方法,最後BeanPostProcessor的postProcessAfterInitialization)
- 應用BeanPostProcessor的postProcessAfterInitialization方法(AOP代理對象生成)在初始化之後被調用
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 { /*判斷beanName是哪個接口的的實現類 如果bean是BeanNameAware接口的實現類會調用setBeanName方法、 如果bean是BeanClassLoaderAware接口的實現類會調用setBeanClassLoader方法、 如果是BeanFactoryAware接口的實現類會調用setBeanFactory方法,注入對應的屬性值。*/ invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //應用BeanPostProcessor的postProcessBeforeInitialization方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //執行初始化方法(先調用InitializingBean的afterPropertiesSet,再調用init-method屬性指定的初始化方法) 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方法(AOP代理對象生成) // AOP是等着對象創建完畢,在進行增強 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
調用初始化方法invokeInitMethods()
- 判斷是否是InitializingBean接口的實現類,如果是縣初始化InitializingBean
- 如果不是則調用InitializingBean接口中的afterPropertiesSet方法
- 然後再初始化標籤對應的init-method屬性中的方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); // 如果是InitializingBean接口的實現類,則先初始化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接口的afterPropertiesSet方法 ((InitializingBean) bean).afterPropertiesSet(); } } // 然後再初始化<bean>標籤對應的init-method屬性中的方法 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); } } }
在initializeBean方法中調用BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法
- 在初始化Bean的時候都會調用每一個配置的BeanPostProcessor的方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; Iterator var4 = this.getBeanPostProcessors().iterator(); do { if (!var4.hasNext()) { return result; } BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next(); //bean初始化後調用 result = beanProcessor.postProcessAfterInitialization(result, beanName); } while(result != null); return result; }
BeanPostProcessor是Spring IOC容器給我們提供的一個擴展接口。接口聲明如下:
public interface BeanPostProcessor { //bean初始化方法調用前被調用 Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; //bean初始化方法調用後被調用 Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }
至此bean的初始化就完成了。
tProcessor)var4.next();
//bean初始化後調用
result = beanProcessor.postProcessAfterInitialization(result, beanName);
} while(result != null);
return result;
}
BeanPostProcessor是Spring IOC容器給我們提供的一個擴展接口。接口聲明如下:
```java
public interface BeanPostProcessor {
//bean初始化方法調用前被調用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化方法調用後被調用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
至此bean的初始化就完成了。
參考:https://www.jianshu.com/p/32dacf644062 作者:GGarrett