相关源码注释
ApplicationContext
Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释
BeanFactory
Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释
本文分析 AbstractApplicationContext 的 obtainFreshBeanFactory()
/**
* <p>
* 获取新的Bean工厂:
* <ol>
* <li>调用供子类实现refreshBeanFactory()方法执行实际的配置加载</li>
* <li>调用供子类实现的getBeanFactory()方法获取子类提供的Bean工厂</li>
* </ol>
* </p>
* Tell the subclass to refresh the internal bean factory.
* <p>告诉子类刷新内部bean工厂。</p>
* @return the fresh BeanFactory instance --新的BeanFactorty实例
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//调用子类实现方法执行实际的配置加载
refreshBeanFactory();
//返回子类提供的Bean工厂,
return getBeanFactory();
}
refreshBeanFactory()
refreshBeanFactory() 是 AbsractApplicationContext 的抽象方法:
/**
* Subclasses must implement this method to perform the actual configuration load.
* The method is invoked by {@link #refresh()} before any other initialization work.
* <p>子类必须实现此方法才能执行实际的配置加载。在进行任何其他舒适化工作之前,该方法由
* {@link #refresh()}调用。</p>
*
* <p>A subclass will either create a new bean factory and hold a reference to it,
* or return a single BeanFactory instance that it holds. In the latter case, it will
* usually throw an IllegalStateException if refreshing the context more than once.
* <p>子类创建一个新的bean工厂并保留对其的引用,或者返回它持有的单个BeanFactory实例。在
* 后一种情况下,如果多次属性上下文,通常会抛出IllegalStateException</p>
*
* @throws BeansException if initialization of the bean factory failed
* -- 如果bean工厂初始化失败
* @throws IllegalStateException if already initialized and multiple refresh
* attempts are not supported
* -- 如果已经初始化并且不支持多次刷新尝试
*/
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
这里仅分析SpringBoot所用到的 GenericApplicationContext 实现:
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
//通过CAS保证修改refreshed值的线程安全,将refreshed修改成true。
if (!this.refreshed.compareAndSet(false, true)) {
//GenericeApplicationContext不支持多次刷新尝试:只需调用一次“刷新”
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
//对bean工厂指定应用程序上下文的ID为bean工程的序列化ID以进行序列化
this.beanFactory.setSerializationId(getId());
}
该方法主要做
- 限制应用程序上下文只能刷新一次
- 指定应用程序上下文的ID为bean工厂的序列化ID以在需要反序列化的 时候进行反序列化
getBeanFactory()
getBeanFactory也是 AbsractApplicationContext 的抽象方法:
/**
* <p>获取当前上下文的BeanFactory对象</p>
* Subclasses must return their internal bean factory here. They should implement the
* lookup efficiently, so that it can be called repeatedly without a performance penalty.
* <p>子类必须在此返回其内部bean工厂。他们应该有效地实现查找,以便可以重复调用它而不
* 影响性能</p>
*
* <p>Note: Subclasses should check whether the context is still active before
* returning the internal bean factory. The internal factory should generally be
* considered unavailable once the context has been closed.
* <p>注意:子类应在返回内部bean工厂之前检验上下文是否仍处于活动状态。一旦关闭上下
* 文,通常应将内部工厂视为不可用,</p>
*
* @return this application context's internal bean factory (never {@code null})
* --此应用程序上下文的内部bean工厂(永远不为{@code null})
* @throws IllegalStateException if the context does not hold an internal bean factory yet
* (usually if {@link #refresh()} has never been called) or if the context has been
* closed already
* -- 如果上下文尚未拥有内部bean工厂(通常是从未调用过{@link #refresh()}),或上下文已经关闭
* @see #refreshBeanFactory()
* @see #closeBeanFactory()
*/
@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
这里仅分析SpringBoot所用到的 GenericApplicationContext 实现:
/**
* Return the single internal BeanFactory held by this context
* (as ConfigurableListableBeanFactory).
* <p>返回由该上下文持有的单个内部BeanFactory(如ConfigurableListableBeanFactory)。</p>
*/
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
GenericApplicationContext 的 beanFactory是在默认构造函数里创建的,beanFactory是 DefaultListableBeanFactory 对象,DefaultListableBeanFactory 也是在Spring最常用,应用最广泛的BeanFactory实例类。
/**
* Create a new GenericApplicationContext.
* <p>创建一个 新的 GenericApplicationContext</p>
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
//DefaultListableBeanFactory:ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的Spring默认实现:
// 一个基于bean定义元数据的成熟的bean工厂,可通过后处理器扩展
this.beanFactory = new DefaultListableBeanFactory();
}