Spring IOC refresh() 之obtainFreshBeanFactory()

#博学谷IT学习技术支持#


我们继续来看spring ioc 的refresh方法

obtainFreshBeanFactory 方法

//在这个阶段进行xml配置文件的解析,加载beanDefinitions
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

spring在启动是,会现将xml配置文件中配置的bean信息加载为beanDefinition。这个加载操作就是在
obtainFreshBeanFactory这个方法中进行的。

看下方法内容:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	//刷新BeanFactory
	refreshBeanFactory();
	return getBeanFactory();
}

refreshBeanFactory

继续跟进refreshBeanFactory方法

	protected final void refreshBeanFactory() throws BeansException {
		// 判断beanFactory是否为空,空为false
		if (hasBeanFactory()) {
			// 如果不为空,则将beanFactory中的Beans都销毁
			// 这里兴趣的可以跟进看下
			destroyBeans();
			// 如果存在beanFactory,则将beanFactory设置为null
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			//自定义BeanFactory,包含是否允许BeanDefinition重写和是否允许循环依赖
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

这里是AbstractRefreshableApplicationContext类中的方法实现。
其中主要做了两个操作
1.初始化beanFactory:
beanFactory的初始化主要在createBeanFactory方法中进行
在beanFactory初始化时,会设置parentBeanFactory,即父级beanFactory,如果没有,则为null。
customizeBeanFactory(beanFactory)这个方法可有子类自行扩展,定制话beanFactory.
AbstractRefreshableApplicationContext类中,主要是两个参数:

	if (this.allowBeanDefinitionOverriding != null) {
	// 1.是否允许beanDefinition重写
	beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
	}
	// 2.是否允许循环引用 这个参数主要用于后面在bean创建时是否允许循环依赖
	// 关于循环依赖,后面在bean的创建过程会讲解
	if (this.allowCircularReferences != null) {
	beanFactory.setAllowCircularReferences(this.allowCircularReferences);
	}

2.加载BeanDefinitions
loadBeanDefinitions(beanFactory);这个方法显而易见就是加载BeanDefinitions的方法了
我们跟进下,默认实现在AbstractXmlApplicationContext类中

	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// 子类实现,初始化beanDefinitionReader属性
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}

1.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
创建一个XmlBeanDefinitionReader类,并将beanFactory传入
将传入的beanFactory赋值给registry属性。
然后还创建了resourceLoader资源解析器和environment,后续会使用evnironment获取一些环境变量系统参数等配置

protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		if (this.registry instanceof ResourceLoader) {
			this.resourceLoader = (ResourceLoader) this.registry;
		}
		else {
			this.resourceLoader = new PathMatchingResourcePatternResolver();
		}

		if (this.registry instanceof EnvironmentCapable) {
			this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
		}
		else {
			this.environment = new StandardEnvironment();
		}
	}

2.beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
loadBeanDefinitions方法,又为beanDefinitionReader重新设置了三个属性。
其中setEntityResolve()是设置实体解析器,用于解析xml的dtd或者schema;

3.initBeanDefinitionReader(beanDefinitionReader);可以由子类继续重写,初始化beanDefinitionReader属性

4.loadBeanDefinitions(beanDefinitionReader);开始执行BeanDefinitions的加载操作。

到这里我们的obtainFreshBeanFactory()方法也就结束了。
不过核心的加载BeanDefinitions操作内容比较复杂,后续将分多章进行详细讲解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值