Springソースシリーズ:BeanDefinitionロード(下)

11645 ワード

Springのソースコードシリーズ:BeanDefinitionではすでに解析過程をほぼ削除しました.本編ではbeanの登録過程を記録します.
beanの登録はDefault Listable BeanFactoryのregister BenDefinition方法で行われます.register BeanDefinitionという方法の具体的なロジックについて説明します.
1、beanDefinitionタイプの判断と検証
ここでの検証は主に、静的工場法と方法を組み合わせて書き換えることができないことを検証することである.
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(),
beanName,"Validation of bean definition failed", ex);
}
}
2、古いbeanをbeanDefinitionMapから取得しようとする
ここではまずbeanNameによってbeanDefinitionMapからBenDefinitionを取りに行きます.そして結果をoldBenDefinitionにあげます.
BeanDefinition oldBeanDefinition;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
3、beanDefinitionMapにはすでにbeanNameというBendefinitionが存在します.
現在のbeanDefinitionMapにすでにbeanNameというBende finitionが存在している場合(すなわち、同じ名前のbeanDefinitionがすでにIoc容器に登録されているかどうかを確認する)、ある場合は、以下の具体策を行う.
beanが上書きされてはいけないなら、直接に投げて再登録できません.beanはすでにこのような異常情報があります.
フレームワークで生成されたBeanを使用して、ユーザがカスタマイズしたbean の代わりに使用する.
既存のBendefinition をカバーします.
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
//
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
//
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
// log
}
else {
// log
}
// Beandefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
4、beanDefinitionMapはBeanNameというBende finitionが存在しません.
//  bean           ,           
if (hasBeanCreationStarted()) {
//Cannot modify startup-time collection elements anymore (for stable iteration)
// ( )( )
// ,
synchronized (this.beanDefinitionMap) {
// beanDefinitionMap
this.beanDefinitionMap.put(beanName, beanDefinition);
// beanName beanDefinitionNames
List updatedDefinitions = new ArrayList(
this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// bean bean name, 。
// , bean bean
if (this.manualSingletonNames.contains(beanName)) {
Set updatedSingletons = new
LinkedHashSet(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
// ,bean
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
5、キャッシュクリアを実行する
1:oldBeanDefinitionが存在する場合、ここに実行しても異常を投げられない場合、このBeanDefinitionはすでに上書きされています.キャッシュは更新が必要です.2:一例モードのbeanオブジェクトであれば、SetにはこのbeanNameが含まれています.ここに実行すると、このBenDefinitionは一例モードのbeanから普通のbeanに変わりました.キャッシュも更新が必要です.
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
OKです.reetBeanDefinitionという方法を見に来ました. bean bean , bean 。
protected void resetBeanDefinition(String beanName) {
// , bean bean 。
clearMergedBeanDefinition(beanName);

// , singleton bean。
// , bean
//( manualSingletonNames )
destroySingleton(beanName);
// bean bean 。
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
if (beanName.equals(bd.getParentName())) {
resetBeanDefinition(bdName);
}
}
}
}
Beanの登録はここまでです.次の勉強はDefaultListable BeanFactoryという集大成者の器です.