spring源码阅读(二)--ioc容器加载(二)--obtainFreshBeanFactory();

直接上源码

/**
*Tell the subclass to refresh the intern+al bean factory
*告诉子类刷新内部bean工厂
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

继续步入得到

	refreshBeanFactory();
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		//判断是否存在bean工厂,如果存在则销毁所有bean,关闭bean工厂
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建默认的bean工厂,DefaultListableBeanFactory beanFactory的实现类,实现了所有生产bean组件的接口,一个完美,功能最全的工厂
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//为容器设置一个序列化ID
			beanFactory.setSerializationId(getId());
			//定制工厂
			customizeBeanFactory(beanFactory);
			//加载我们的bean定义 类似于生产图纸
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

从上面代码可以得知,spring在初始化容器的时候会先去判断是否存在bean工厂,如果存在会对所有的bean进行销毁处理,关闭掉bean工厂。然后继续创建bean工厂,之后会设置容器序列化id,定制bean工厂的一些属性,最后加载BeanDefinition,然后将bean工厂设置本类的到属性中

继续跟进createBeanFactory()方法

	protected DefaultListableBeanFactory createBeanFactory() {
		//创建一个功能最全的bean工厂,我们可以吧spring当成一个大工厂,里面的每个接口组件是负责生产bean的零件,最后拼接成一个完整的工厂
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());getBeanFactory()
	}

	//判断父容器是不是属于ConfigurableApplicationContext容器,如果是调用父容器的getBeanFactory()获取bean工厂,如果不是则将自己设置为夫容器节点,
	@Nullable
	protected BeanFactory getInternalParentBeanFactory() {
		return (getParent() instanceof ConfigurableApplicationContext ?
				((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());
	}

下面是DefaultListableBeanFactory的组件依赖图,可以看见DefaultListableBeanFactory的层级是最深的,实现了所有功能接口,是功能最完善的工厂
在这里插入图片描述
定制bean工厂的属性

	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		//判断是否复写了allowBeanDefinitionOverriding,spring用于处理重名bean的问题,当allowBeanDefinitionOverriding为true时,
		//则表示会覆盖之前的bean,该值默认是false值,一般项目中需要将其值设置为ture
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//是否支持循环引用,默认是true支持循环引用的,如果设置为false,表示不支持,如果此时创建bean的时候发现有循环运用,则会抛异常
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

继续跟进loadBeanDefinitions(beanFactory)

	//加载我们的bean定义 类似于生产图纸
			loadBeanDefinitions(beanFactory);

该方法主要是加载bean的定义在我们的工厂中,bean定义可以类比为生产bean的图纸,里面记载了bean的名称。bean是否是单例的,是否懒加载,等等,当然bean定义被加载之后也是可以对bean定义进行修改的

	//模板方法,把父类定义的足够高,以抛异常的形式强迫之类必须实现该方法,
	protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
			throws BeansException, IOException;

我们采用的是读取xml的形式来初始化容器

	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		//获取一个XmlBeanDefinition资源加载器
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
		/**
		 * 给加载器设置环境变量,
		 */
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
		//初始化beanDefinitionReader资源加载器
		initBeanDefinitionReader(beanDefinitionReader);
		//根据bean定义的读取器,读取并加载BeanDefinitions
		loadBeanDefinitions(beanDefinitionReader);
	}

接着跟进去loadBeanDefinitions(beanDefinitionReader)

public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
	//省略其他代码,主要是这一行进行真正的加载
		int count = loadBeanDefinitions(resources);
}



public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
	//spring里面,凡是带do的都是真正干活的
	return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}



protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
			Document doc = doLoadDocument(inputSource, resource);
			/**
			 * 注册beanDefinition ,到此开始注册bean定义信息
			 */
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
}




protected void doRegisterBeanDefinitions(Element root) {
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);

		if (this.delegate.isDefaultNamespace(root)) {
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				// We cannot use Profiles.of(...) since profile expressions are not supported
				// in XML config. See SPR-12458 for details.
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}
		//留给子类重写,类似前置处理器,这里spring预留了拓展点,给子类进行前置和后置处理
		preProcessXml(root);
		//真正解析bean定义信息
		parseBeanDefinitions(root, this.delegate);
		//留给子类重写,类似后置处理器
		postProcessXml(root);

		this.delegate = parent;
	}		

至此obtainFreshBeanFactory()方法就讲解完毕,到此我们的bean工厂就已经注册好了bean的定义和一些bean工厂的定制信息,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值