Spring源码之ApplicationContext(三)加载BeanFactory

准备好了环境之后,接下来要做的事情是初始化BeanFactory,并进行XML文件读取。总的一句话就是加载BeanFactory。那么Spring是如何实现这个功能呢?接下来笔者就要分析。在分析之前,我们先看一张时序图。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)


1. AbstractRefreshableApplicationContext

     跟踪程序的执行,代码将进入AbstractRefreshableApplicationContext类的refreshBeanFactory的函数。在这里主要做的事情就是:

1)        创建DefaultListableBeanFactory

2)        指定序列化ID

3)        定制BeanFactory

4)        加载BeanDefinition

5)        使用全局变量记录BeanFactory类实例

 protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//创建DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			//为了序列化指定id,如果需要的话,让BeanFactory从id反序列化到BeanFactory对象
			beanFactory.setSerializationId(getId());
			//定制beanFactory,设置相关属性,包括是否允许覆盖名称的不同定义的对象及循环依赖以及
			//设置@Autowired和@Qualifier,注解解析 器QualifierAnnotationAutowireCandidateResolver
			<strong>customizeBeanFactory(beanFactory)</strong>;
			//初始化DodumentReader,并进行XML文件读取及解析
			<strong>loadBeanDefinitions(beanFactory)</strong>;
			synchronized (this.beanFactoryMonitor) {
				<strong>this.beanFactory = beanFactory</strong>;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

在这个函数中,我们先来看第一个关键的函数customizeBeanFactory。这里开如了对BeanFactory的扩展,在基本容器的基础上,增加了是否允许覆盖,是否允许扩展的设置,并提供了注解@Qualifier和@Autowired的支持。

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		//如果属性allowBeanDefinitionOverriding不为空,设置给beanFactory对象相应属性
		//此属性含义:是否允许覆盖同名称的不同定义对象
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		//如果属性allowCircularReferences不为空,设置给beanFactory对象相应属性
		//此属性的含义:是否允许bean之间存循环依赖
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
		//用于@Qualifier和@Autowired
		beanFactory.setAutowireCandidateResolver(<strong>new QualifierAnnotationAutowireCandidateResolver()</strong>);
	}

2. QualifierAnnotationAutowireCandidateResolver 

   在上面的定制BeanFactory的函数中,我们还要注意最后的一个方法,那就是去实例化QualifierAnnotationAutowireCandidateResolver,其实就是去实现这个类的getSuggestValue()的函数。

public Object getSuggestedValue(DependencyDescriptor descriptor) {
		Object value = findValue(descriptor.getAnnotations());
		if (value == null) {
			MethodParameter methodParam = descriptor.getMethodParameter();
			if (methodParam != null) {
				value = findValue(methodParam.getMethodAnnotations());
			}
		}
		return value;
	}

3. AbstractXmlApplicationContext

接下来,我们还是要回到refreshBeanFactory()的函数中,还有一个重要的方法,那就是loadBeanDefinitions().这个函数其实就是在类AbstractXmlApplicationContext里的,实现的具体过程如下。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		//为指定beanFactory创建XmlBeanDefinitionReader
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		//对beanDefinitionReader进行环境变量设置
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		//对BeanDefinitionReader进行设置,可以覆盖
		initBeanDefinitionReader(beanDefinitionReader);
		<strong>loadBeanDefinitions(beanDefinitionReader)</strong>;
	}
而最后一个loadBeanDefinitions的方法就是在这个类中的,所以它的实现如下。

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

4.总结

   这一节主要分析的是初始化BeanFactory,并进行XML文件读取。这里首先就是要定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖,及主,设置@Autowired和@Qualifier注解解析器QualifierAnnotationAutowireCandidateResolver 。其次就是初始化DodumentReader,并进行XML文件读取及解析。







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值