Spring 5 ApplicationContext#refresh() -- obtainFreshBeanFactory()源码解析

相关源码注释

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());
	}

该方法主要做

  1. 限制应用程序上下文只能刷新一次
  2. 指定应用程序上下文的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();
	}

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108322966