08.Spring Bean 註冊 - BeanDefinitionRegistry
阿新 • • 發佈:2018-07-22
ace 過程 markdown itl title 描述 nco ack new
基本概念
BeanDefinitionRegistry ,該類的作用主要是向註冊表中註冊 BeanDefinition 實例,完成 註冊的過程。
它的接口定義如下:
public interface BeanDefinitionRegistry extends AliasRegistry {
// 關鍵 -> 往註冊表中註冊一個新的 BeanDefinition 實例
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;
// 移除註冊表中已註冊的 BeanDefinition 實例
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 從註冊中取得指定的 BeanDefinition 實例
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 判斷 BeanDefinition 實例是否在註冊表中(是否註冊)
boolean containsBeanDefinition(String beanName);
// 取得註冊表中所有 BeanDefinition 實例的 beanName(標識)
String[] getBeanDefinitionNames();
// 返回註冊表中 BeanDefinition 實例的數量
int getBeanDefinitionCount();
// beanName(標識)是否被占用
boolean isBeanNameInUse(String beanName);
}
再來看它的繼承關系:
2.DefaultListableBeanFactory
該類是 BeanDefinitionRegistry 接口的基本實現類,但同時也實現其他了接口的功能,這裏只探究下其關於註冊 BeanDefinition 實例的相關方法 。
首先來看它的成員變量:
// 關鍵-> 註冊表,由 BeanDefinition 的標識 (beanName) 與其實例組成
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, bean>(64);
// 標識(beanName)集合
private final List<String> beanDefinitionNames = new ArrayList<String>(64);
再來看 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法。該方法的主要作用是調用註冊器(DefaultListableBeanFactory)完成註冊過程。
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) {
try {
// BeanDefinition 校驗
((AbstractBeanDefinition) beanDefinition).validate();
}catch (BeanDefinitionValidationException ex) {
// 拋出異常...
}
}
BeanDefinition oldBeanDefinition;
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
// 拋出異常...
}else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// 日誌輸出...
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
// 日誌輸出...
}
else {
// 日誌輸出...
}
}else {
// 添加標識進 List
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
}
// 關鍵 -> 添加進 map
this.beanDefinitionMap.put(beanName, beanDefinition);
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
觀察代碼可以發現該方法最重要的步驟其實就是:
this.beanDefinitionMap.put(beanName, beanDefinition);
也就是向註冊表中(beanDefinitionMap)添加 BeanDefinition 實例,完成註冊的過程。
08.Spring Bean 註冊 - BeanDefinitionRegistry