Spring的一個非常重要的概念的就是Bean
,Spring容器需要通過掃描和註冊來實現對Bean
信息的管理。在分析了Spring的源碼之後發現,Spring裏面用了很多的BeanFactory
,這個類非常重要,因爲實際上在Spring中BeanFactory
是IOC
容器的實際代表者,它用來創建和管理Bean
。它爲其他具體的IOC
容器提供了最基本的規範,它是一個接口類型。
BeanFactory
是最典型的工廠方法模式。不同類型的工廠會生產不同類型的商品。它的子接口和對應的實現類結構如下:
1. BeanFactory
接口
我們可以看到在BeanFactory
接口下面有三個子接口:
HierarchicalBeanFactory
:提供父容器的訪問功能ConfigurableBeanFactory
接口
AutowireCapableBeanFactory
:在BeanFactory
基礎上是實現了對已存在實例的管理ListableBeanFactory
:提供了批量獲取Bean
的方法
接口ConfigurableListableBeanFactory
繼承了上述的三個接口,增加了一些其他的功能:如類加載器、類型轉換,屬性編輯器,BeanPostProcessor
,Bean
定義等
實現類DefaultListableBeanFactory
繼承ConfigurableListableBeanFactory
接口,實現了所有的BeanFactory
功能,且可以註冊BeanDefinition
1.1 ListableBeanFactory
接口
上面的第一個圖片沒有截全,遺漏了ListableBeanFactory
的部分實現類信息,且這個實現類還比較重要,因此再增加一個圖片。
我們可以看到AnnotataionConfigApplicationContext
實現了ListableBeanFactory
接口。AnnotataionConfigApplicationContext
類是註解驅動去掃描Bean
的定義信息。這個類我們很熟悉,因爲在Spring啓動的時候就是利用這個類:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig_AOP.class);
在使用BeanFactory
工廠創建Bean
的過程中,我們需要利用BeanDefinitionRegistry
將這些Bean
註冊到DefaultListableBeanFactory
中。那麼接下來就介紹一下BeanDefinitionRegistry
2. BeanDefinitionRegistry
接口
public interface BeanDefinitionRegistry extends AliasRegistry
從上述代碼可以看出,BeanDefinitionRegistry
接口實現了AliasRegistry
接口,它主要的工作就是定義Bean
的常規操作。
它有三個子接口:
SimpleBeanDefinitionRegistry
實現類DefaultListableBeanFactory
實現類- 基本實現類 ,擁有
registryBeanDefinition
功能
- 基本實現類 ,擁有
GenericApplicationContext
實現類
2.1 BeanDefinitionRegistry
接口的功能
public interface BeanDefinitionRegistry extends AliasRegistry {
// 向beanFactory中註冊一個BeanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
// 根據beanName從beanFactory中移除一個已經註冊的BeanDefinition
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 根據beanName從beanFactory中獲取一個BeanDefinition
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
// 判斷beanFactory中是否有beanName的BeanDefinition
boolean containsBeanDefinition(String beanName);
// 獲取beanFactory中的所有BeanDefinition的beanName
String[] getBeanDefinitionNames();
// 獲取beanFactory中的BeanDefinition的數量
int getBeanDefinitionCount();
// 判斷beanFactory中的beanName是否被佔用
boolean isBeanNameInUse(String beanName);
}
2.2 SimpleBeanDefinitionRegistry
類
是BeanDefinitionRegistry
的一個簡單實現方式,沒有內置的beanFactory,這個類是用來留給我們測試用的。開發情況下Spring不會使用該類。
這個類的功能很簡單,這裏就不做詳細介紹了,根據方法的名稱就可以看出對應的方法所實現的功能。
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
// 使用ConcurrentHashMap來存儲beanName和BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
this.beanDefinitionMap.put(beanName, beanDefinition);
}
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
if (this.beanDefinitionMap.remove(beanName) == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
}
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
@Override
public boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
@Override
public String[] getBeanDefinitionNames() {
return StringUtils.toStringArray(this.beanDefinitionMap.keySet());
}
@Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}
@Override
public boolean isBeanNameInUse(String beanName) {
return isAlias(beanName) || containsBeanDefinition(beanName);
}
}
2.3 DefaultListableBeanFactory
類
這個類非常重要,它是BeanDefinitionResgitry
接口的基本實現,實際上很多beanFactory
最後都是調用DefaultListableBeanFactory
類的registryBeanFactory
來註冊beanDefinition
.
這個類裏面有非常多的方法,這裏只介紹比較重要的registryBeanFactory
方法的實現
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
// 以Map的數據結構保存beanName和BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
// 保存所有beanDefinition的名字
private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
// 註冊BeanDefinition的信息
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 {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
// 先判斷當前的beanName對應的bean信息是否已經存在
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
// 是否允許覆蓋
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
// 若允許覆蓋 那還得比較下role 如果新進來的這個Bean的role更大
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// hasBeanCreationStarted:說明已經存在bean已經在創建了
synchronized (this.beanDefinitionMap) {
// 將beanName和beanDefinition放進去
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// 仍然處在Spring啓動階段
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
2.4AnnotationConfigApplicationContext
類
這個類是GenericApplicationContext
的子類,但是通過分析這個類的方法,發現並沒有registryBeanDefinition
方法。
雖然沒有registryBeanDefinition
方法,但是又register
方法,而register
方法又調用了AnnotatedBeanDefinitionReader
類的register
方法,經過一系列的操作,最後調用了DefaultListableBeanFactory
類的registerBeanDefinition
方法
3 總結
- Spring使用
BeanFactory
作爲創建Bean
的工廠,利用BeanDefinitionRegistry
來註冊BeanDefinition
,實際上都是使用DefaultListableBeanFactory
類的registerBeanDefinition
。