Spring源码 - 容器刷新#obtainFreshBeanFactory()

Spring源码 - 容器刷新obtainFreshBeanFactory()

Spring版本:Spring 5.3.13-release


# 1、obtainFreshBeanFactory()获取BeanFactory

obtainFreshBeanFactory()Spring容器刷新的第二个方法,其字面意思为获取新鲜的Bean工厂。为AbstractApplicationContext获取BeanFactory使其具备Bean的一些列基本操作能力。为后续的工作提供帮助。

AbstractApplicationContext#obtainFreshBeanFactory()代码:

	/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 初始化 beanFactory, 并进行配置读取(XML 或配置类), 并将获取的 beanFactory 记录在当前实体的属性中
		refreshBeanFactory();
		// 返回当前实体的 beanFactory 属性
		return getBeanFactory();
	}

这里代码很清晰,SpringBeanFactory的创建委派给refreshBeanFactory()方法。refreshBeanFactory()AbstractApplicationContext类中的抽象方法,这里使用委派模式,将BeanFactory的创建委派给refreshBeanFactory()方法,自己并不关心创建过程。


# 2、BeanFactory的创建过程

AbstractApplicationContext#refreshBeanFactory() 方法被两个类实现AbstractRefreshableApplicationContextGenericApplicationContext

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
# 1、GenericApplicationContext#refreshBeanFactory()

GenericApplicationContext#refreshBeanFactory()代码片段:

	private final DefaultListableBeanFactory beanFactory;

	/**
	 * Create a new GenericApplicationContext.
	 * @see #registerBeanDefinition
	 * @see #refresh
	 */
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

	/**
	 * Create a new GenericApplicationContext with the given DefaultListableBeanFactory.
	 * @param beanFactory the DefaultListableBeanFactory instance to use for this context
	 * @see #registerBeanDefinition
	 * @see #refresh
	 */
	public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {
		Assert.notNull(beanFactory, "BeanFactory must not be null");
		this.beanFactory = beanFactory;
	}

	/**
	 * Do nothing: We hold a single internal BeanFactory and rely on callers
	 * to register beans through our public methods (or the BeanFactory's).
	 * @see #registerBeanDefinition
	 */
	@Override
	protected final void refreshBeanFactory() throws IllegalStateException {
		// CAS 将容器刷新状态设置为 true
		if (!this.refreshed.compareAndSet(false, true)) {
			throw new IllegalStateException(
					"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
		}
		// 设置 beanFactory 的序列化 id
		this.beanFactory.setSerializationId(getId());
	}

GenericApplicationContext中的操作很简单,只是将容器刷新状态设置为true,然后设置BeanFactory的序列化id

通过构造函数可以很清晰的看到,GenericApplicationContext中的BeanFactory类型为DefaultListableBeanFactory,这也是Spring默认的BeanFactory


# 2、AbstractRefreshableApplicationContext#refreshBeanFactory()

AbstractRefreshableApplicationContext#refreshBeanFactory()代码片段:

	/** Bean factory for this context. */
	@Nullable
	private volatile DefaultListableBeanFactory beanFactory;

	/**
	 * 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.
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		// 如果存在 BeanFactory 则销毁 BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 创建 DefaultListableBeanFactory 对象
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			// 为了序列化自指定 id, 可以从 id 反序列化获取到 BeanFactory 对象
			beanFactory.setSerializationId(getId());
			// 定制 BeanFactory, 设置相关属性, 包括是否允许覆盖同名称的不同定义的对象以及循环依赖
			customizeBeanFactory(beanFactory);
			// 初始化 DocumentReader, 并进行 XML 文件读取及解析, 默认命名空间的解析, 自定标签的解析
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

	/**
	 * 创建 DefaultListableBeanFactory
	 *
	 * Create an internal bean factory for this context.
	 * Called for each {@link #refresh()} attempt.
	 * <p>The default implementation creates a
	 * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}
	 * with the {@linkplain #getInternalParentBeanFactory() internal bean factory} of this
	 * context's parent as parent bean factory. Can be overridden in subclasses,
	 * for example to customize DefaultListableBeanFactory's settings.
	 * @return the bean factory for this context
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
	 * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
	 */
	protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}
  • 首先判断是否有BeanFactory,如果有则先进行销毁。
  • 通过createBeanFactory()方法创建BeanFactorycreateBeanFactory()返回的也是DefaultListableBeanFactory类型的BeanFactory
  • 定制BeanFactory, 设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖。
  • 初始化DocumentReader,并进行XML文件读取及解析,默认命名空间的解析,自定标签的解析。

GitHub源码地址https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值