整体认识
先来看一下整体架构图。
从该类的名字可以看出来,是为了容器刷新而存在的
该类名称:可刷新的ApllicationContext容器抽象类。
每次刷新容器要干的事就是重新将bean注册到容器中,至于以哪样的策略来实现bean注册,这要具体看Spring如何实现的。其子类唯一实现的方法就是loadBeanDefinitions()方法。
具体认识
1. 属性
@Nullable
// 是否允许bean定义被同名的bean定义覆盖
private Boolean allowBeanDefinitionOverriding;
// 是否允许循环引用标志位
@Nullable
private Boolean allowCircularReferences;
/** Bean factory for this context. */
// 当前容器Bean工厂
@Nullable
private volatile DefaultListableBeanFactory beanFactory;
两个标志的set方法,两个标志的默认是都是true,这里不再赘述。
/**
* Set whether it should be allowed to override bean definitions by registering
* a different definition with the same name, automatically replacing the former.
* If not, an exception will be thrown. Default is "true".
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
*/
public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
}
/**
* Set whether to allow circular references between beans - and automatically
* try to resolve them.
* <p>Default is "true". Turn this off to throw an exception when encountering
* a circular reference, disallowing them completely.
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
*/
public void setAllowCircularReferences(boolean allowCircularReferences) {
this.allowCircularReferences = allowCircularReferences;
}
2. 刷新bean工厂
/**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
* ~~~~~~~~~~~~~~~~~~~~~~~~
* 此实现对该上下文的基础bean工厂执行实际的刷新
* 关闭前一个bean工厂(如果有),并为该上下文生命周期的下一阶段初始化一个新的bean工厂
* ~~~~~~~~~~~~~~~~~~~~~~~~
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
// 判断当前容器是够有Bean工厂,如果有的话直接关闭该bean工厂
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建新的bean工厂,之前存在的已经关闭了
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 指定一个ID以进行序列化,这里指定的是容器id,如果需要的话
// 允许将该BeanFactory从该ID反序列化回BeanFactory对象
beanFactory.setSerializationId(getId());
// 定制容器使用的内部bean工厂
customizeBeanFactory(beanFactory);
// 委托多个bean加载器,将bean定义加载到指定的bean工厂中
loadBeanDefinitions(beanFactory);
// bean工厂赋值
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
2.1 序列化bean工厂
/**
* Specify an id for serialization purposes, allowing this BeanFactory to be
* deserialized from this id back into the BeanFactory object, if needed.
* ~~~~~~~~~~~~~~~~~~~~~~~~~~
* 指定一个ID以进行序列化,如果需要的话,允许将该BeanFactory从该ID反序列化回BeanFactory对象
* ~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public void setSerializationId(@Nullable String serializationId) {
if (serializationId != null) {
serializableFactories.put(serializationId, new WeakReference<>(this));
}
else if (this.serializationId != null) {
serializableFactories.remove(this.serializationId);
}
this.serializationId = serializationId;
}
2.2 定制容器使用的内部bean工厂
看源码可知道也就是设置bean定义是否可覆盖和循环引用标志
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
关闭容器刷新和bean工厂
@Override
// 关闭容器刷新
protected void cancelRefresh(BeansException ex) {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory != null) {
beanFactory.setSerializationId(null);
}
super.cancelRefresh(ex);
}
// 关闭bean工厂
@Override
protected final void closeBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory != null) {
beanFactory.setSerializationId(null);
this.beanFactory = null;
}
}
获取bean工厂
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
至此所有重要的方法就了解完了
总结
这个类是简单的,但是要知道这个类的具体作用是什么。
由名字可以知道,该类主要是容器的刷新
- 设置了标志位来决定是否覆盖bean定义和循环引用
- 刷新容器肯定要重新定制bean工厂,定制bean工厂是该类的重要功能
该类的所有功能都是为了容器刷新做准备,至于容器刷新所需要读取配置文件,加载beanDefinition则是由AbstractRefreshableConfigApplicationContext来完成。Spring的优良做法就是看见类名就能大概知道该类的所提供的功能。