Spring源码私家笔记——BeanFactory被创建

Spring源码 - BeanDefinition的加载

重点关注org.springframework.context.support.AbstractApplicationContext#refresh中调用的

obtainFreshBeanFactory方法,这个方法也在AbstractApplicationContext中

/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

注释写的简单,告诉子类来刷新内部的beanFactory,返回被刷新的BeanFactory实例

getBeanFactory就是返回已经实例化好的beanFactory,比较简单。所以我们重点关注refreshBeanFactory

/**
	 * 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 {
    // 既然是刷新,则要检查一下,是否要先销毁已有的Bean和BeanFactory实例
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
    
		try {
      // 创建BeanFactory实例
			DefaultListableBeanFactory beanFactory = createBeanFactory();
      // 设置唯一序列号ID
			beanFactory.setSerializationId(getId());
      // 留给子类扩展,对BeanFactory做一些个性化设置
			customizeBeanFactory(beanFactory);
      // 加载BeanDefinition
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			// 省略
		}
	}

以上,很清楚的看到创建刷新BeanFactory的几个关键事项:

  1. 创建BeanFactory实例 createBeanFactory()
  2. 留给子类扩展,对BeanFactory做一些个性化设置 customizeBeanFactory(beanFactory)
  3. 加载BeanDefinition loadBeanDefinitions(beanFactory)

BeanFactory的实例化

先来看BeanFactory的创建

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

注释写的很清楚,为context创建一个beanFactory,因为创建的是DefaultListableBeanFactory的实例,在下一步customizeBeanFactory(beanFactory)中,我们就可以调用它的一些方法来设置是否允许BeanDefinition定义覆盖、是否允许循环引用等,然后在AbstractAutowireCapableBeanFactory的构造器中,设置了几个Aware类的依赖注入检查

/**
 * Create a new AbstractAutowireCapableBeanFactory.
 */
public AbstractAutowireCapableBeanFactory() {
   super();
   ignoreDependencyInterface(BeanNameAware.class);
   ignoreDependencyInterface(BeanFactoryAware.class);
   ignoreDependencyInterface(BeanClassLoaderAware.class);
}

AbstractAutowireCapableBeanFactory中设置了父BeanFactory(如果有的话)

/**
 * Create a new AbstractAutowireCapableBeanFactory with the given parent.
 * @param parentBeanFactory parent bean factory, or {@code null} if none
 */
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
   this();
   setParentBeanFactory(parentBeanFactory);
}

还记得我们创建的BeanFactory是new的那个子类吗?对,是``,我们也可以通过类图来大概看一下它具备那些能力和属性

在这里插入图片描述

解释一个几个Registry(注册器)

  • AliasRegistry 要求子类实现提供别名的管理能力(注册、查询等接口)
  • BeanDefinitionRegistry 要求子类实现提供BeanDefinitition的管理能力
  • SingletonBeanRegistry 要求子类实现提供单例Bean的管理能力
    所有new出来的这个DefaultListableBeanFactory就必定有这些相关的接口

对BeanFactory的个性化设置

/**
	 * Customize the internal bean factory used by this context.
	 * Called for each {@link #refresh()} attempt.
	 * <p>The default implementation applies this context's
	 * {@linkplain #setAllowBeanDefinitionOverriding "allowBeanDefinitionOverriding"}
	 * and {@linkplain #setAllowCircularReferences "allowCircularReferences"} settings,
	 * if specified. Can be overridden in subclasses to customize any of
	 * {@link DefaultListableBeanFactory}'s settings.
	 * @param beanFactory the newly created bean factory for this context
	 * @see DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
	 * @see DefaultListableBeanFactory#setAllowCircularReferences
	 * @see DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
	 * @see DefaultListableBeanFactory#setAllowEagerClassLoading
	 */
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

上面已经提到过了,我们列举几个典型的可被覆盖的BeanFactory属性

  • setAllowBeanDefinitionOverriding 是否允许BeanDefinition覆盖,有多个配置来源时可能会产生命名冲突等,这个设置也对Bean的别名覆盖生效。为false时,如果有冲突会抛异常
  • setAllowCircularReferences 是否允许Bean之间的循环引用,为true时(默认)会自动解决循环依赖
  • setAllowRawInjectionDespiteWrapping 是否允许原始Bean(没有切面和装饰)的注入,默认FALSE,不那么常用,也不鼓励使用
  • setAllowEagerClassLoading 是否允许Bean的Class提前加载,及时被标识为lazy-init,默认true

加载BeanDefinition

自此,我们就已经得到了一个BeanFactory对象,这之后,我们将使用BeanFactory实例完成一系列的后续工作。在refreshBeanFactory中,则有非常重要的一步——loadBeanDefinitions(beanFactory),这里面的源码真的是很庞大,我们还是挑重点进行讲解。
在这里插入图片描述
BeanDefinition的加载流程请看下个章节:
Spring源码私家笔记——BeanDefinition加载流程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值