SprigBenの初期化のBean作成準備---メインラインロジック(三)
5773 ワード
前の章でキャッシュから単一の例を取得して簡単に分析しましたが、キャッシュに既にロードされていないbeanは最初からbeanのロードプロセスを開始します.
public Object getSingleton(String beanName,Object Factory)singleton Factory){ Asert.notNull(beanName,「Ben name must not be null」)
コードとその関連コメント:
上記のコードはbeanを作成する操作ではなく、beanを作成するための準備をしています.
Step 1:キャッシュが既に読み込まれているか確認する
Step 2:ローディングしていないと、beanNameのローディング状態を記録します.
Step 3:読み込みの前にロード状態を記録します.
そのうち beforeSingleton Creationはロード状態を記録し、ロードされているbeanNameをsingletons CurrenntlyInCreationにキャッシュする.
step 4:Object FactoryによるgetObjectの実例化bean
ステップ5: 後処理 afterSingleton Creation
ここでafterSingleton Creationとは、beanローディングが終了したら、バッファを削除して、beanに対して状態記録をロードしています.
Step 6:beanをキャッシュし、関連する補助レコードを削除します.
次にコアコードブロックを見ます.
次に簡単にcreateBenを分析します.
Step 1:クラス設定の属性またはクラスNameによってクラスを解析します.
Step 2:override属性を検証し、マークする(lookup-methodとreplacceMethodを解決する)
step 3:resoveBefore Instantiationでは、beanが初期化前の短絡操作であるかどうかを解析します.
ステップ4:beanを作成します.
public Object getSingleton(String beanName,Object Factory)singleton Factory){ Asert.notNull(beanName,「Ben name must not be null」)
コードとその関連コメント:
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//
synchronized (this.singletonObjects) {
// bean , bean
Object singletonObject = this.singletonObjects.get(beanName);
// singleton bean
if (singletonObject == null) {
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 + "'");
}
//
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// bean
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) {
//
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
説明: 上記のコードはbeanを作成する操作ではなく、beanを作成するための準備をしています.
Step 1:キャッシュが既に読み込まれているか確認する
Step 2:ローディングしていないと、beanNameのローディング状態を記録します.
Step 3:読み込みの前にロード状態を記録します.
そのうち beforeSingleton Creationはロード状態を記録し、ロードされているbeanNameをsingletons CurrenntlyInCreationにキャッシュする.
step 4:Object FactoryによるgetObjectの実例化bean
ステップ5: 後処理 afterSingleton Creation
ここでafterSingleton Creationとは、beanローディングが終了したら、バッファを削除して、beanに対して状態記録をロードしています.
Step 6:beanをキャッシュし、関連する補助レコードを削除します.
次にコアコードブロックを見ます.
sharedInstance = getSingleton( beanName, () -> {
try {
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.
//
destroySingleton(beanName);
throw ex;
}
});
get Singletonには、フィードバックの関数があります.crate Bean、つまりgetSingletonのObject Factoryです.本当にbeanを作成する操作は、このcreateBen方法です.次に簡単にcreateBenを分析します.
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 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.
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.
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 {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
ステップの説明:Step 1:クラス設定の属性またはクラスNameによってクラスを解析します.
Step 2:override属性を検証し、マークする(lookup-methodとreplacceMethodを解決する)
step 3:resoveBefore Instantiationでは、beanが初期化前の短絡操作であるかどうかを解析します.
ステップ4:beanを作成します.