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
。