開始例項化
AbstractAutowireCapableBeanFactory 類實現了ObjectFactory 介面,建立容器指定的Bean 例項物件,同時還對建立的Bean 例項物件進行初始化處理。其建立Bean 例項物件的方法原始碼如下:
//建立Bean例項物件
@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<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
//校驗和準備Bean中的方法覆蓋
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.
//如果Bean配置了初始化前和初始化後的處理器,則試圖返回一個需要建立Bean的代理物件
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//建立Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
// A previously detected exception with proper bean creation context already...
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
//真正建立Bean的方法
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()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
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.
//呼叫PostProcessor後置處理器
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.
//向容器中快取單例模式的Bean物件,以防迴圈引用
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");
}
//這裡是一個匿名內部類,為了防止迴圈引用,儘早持有物件的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
//Bean物件的初始化,依賴注入在此觸發
//這個exposedObject在初始化完成之後返回作為依賴注入完成後的Bean
Object exposedObject = bean;
try {
//將Bean例項物件封裝,並且Bean定義中配置的屬性值賦值給例項物件
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean物件
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);
}
}
if (earlySingletonExposure) {
//獲取指定名稱的已註冊的單例模式Bean物件
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//根據名稱獲取的已註冊的Bean和正在例項化的Bean是同一個
if (exposedObject == bean) {
//當前例項化的Bean初始化完成
exposedObject = earlySingletonReference;
}
//當前Bean依賴其他Bean,並且當發生迴圈引用時不允許新建立例項物件
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
//獲取當前Bean所依賴的其他Bean
for (String dependentBean : dependentBeans) {
//對依賴Bean進行型別檢查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
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 {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
通過上面的原始碼註釋,我們看到具體的依賴注入實現其實就在以下兩個方法中:
1)、createBeanInstance()方法,生成Bean 所包含的java 物件例項。
2)、populateBean()方法,對Bean 屬性的依賴注入進行處理。
下面繼續分析這兩個方法的程式碼實現。
相關文章
- php例項化物件的例項方法PHP物件
- 例項化list
- Java--例項化Java
- Laravel kernel例項化Laravel
- ASP.NET Web API自身對CORS的支援:從例項開始ASP.NETWebAPICORS
- Grails國際化例項AI
- 如何區分例項化網格中的每個例項
- Java類初始化和例項化Java
- Dart - 抽象類的例項化Dart抽象
- [Android]Gank 元件化例項AppAndroid元件化APP
- vue、react隱式例項化VueReact
- Maven例項講解教程,從零開始學Maven,帶你快速入門!Maven
- [MobX State Tree資料元件化開發][2]:例項-TodoList元件化
- ArcGIS開發(二)——一個基本視窗的例項化
- python類例項化如何實現Python
- JVM初探(五):類的例項化JVM
- 介面到底能不能例項化
- bean例項化的三種方法Bean
- 從零開始學 Web 之 Vue.js(三)Vue例項的生命週期WebVue.js
- C#開發例項大全C#
- Java開發學習(四)----bean的三種例項化方式JavaBean
- python開發例項-python開發案例Python
- C# Winform程式介面優化例項C#ORM優化
- python呼叫方法必須例項化麼Python
- Java介面為什麼不能例項化Java
- 分享一個SQLite 效能優化例項SQLite優化
- 類的例項化順序和分析
- css背景虛化效果程式碼例項CSS
- python中類的建立和例項化Python
- 優化 WebView 的載入速度例項優化WebView
- 資料庫正規化與例項資料庫
- CSS 例項之開啟大門CSS
- Spring 原始碼學習 - 單例bean的例項化過程Spring原始碼單例Bean
- Spring中Bean的例項化詳細流程SpringBean
- Python中類建立和例項化過程Python
- 例項演示如何使用CCE XGPU虛擬化GPU
- 整明白 Golang struct 例項化和賦值GolangStruct賦值
- java中父類宣告子類例項化Java