传送门spring
BeanFactory
加载 XML
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicaitonContext.xml"));
Ps:由于我是跟着《Spring源码深度解析》学习的,而这本书出版在13年9月,这一种方法在新的Spring
版本中已经废弃掉了,取而代之的是下面的方法;但既然学了,那就仍是记录一下,学习一下开发者的思想也是不错的.数组
ApplicationContext
加载 XML
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
上述二者都是经过加载XMl
配置文件的方式加载Bean
,然后者是前者的扩展,提供了更多的功能,即ApplicationContext
拥有BeanFactory
的所有功能,在绝大多数的"典型的"企业应用和系统,ApplicationContext
都优先于BeanFactory
.app
BeanFactory
是延迟加载,若是一个Bean
当中存在属性没有加载,会在第一次调用getBean()
方法的时候报错,而ApplicationContext
会在读取Xml
文件后,若是配置文件没有错误,就会将全部的Bean
加载到内存中,缺点就是在Bean
较多的时候比较占内存,程序启动较慢.函数
Spring
容器加载中最重要的两个类XmlBeanFactory
继承自DefaultListableBeanFactory
,然后者是整个Bean
加载的核心部分,是Spring
注册及加载Bean
的默认实现,而XmlBeanFactory
使用了自定义的Xml
读取器XmlBeanDefinitionReader
,实现了个性化的BeanDefinitionReader
读取.学习
主要负责Xml
文件的读取、解析和注册功能this
上面的两种方法的处理大体相同,让咱们经过时序图看看二者在加载时的区别:code
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicaitonContext.xml"));
粗略时序图:xml
首先,将applicationContext.xml
用ClassPathResource
进行封装获得Resource
资源,Resource
接口将全部的资源文件统一处理,当经过Resource
相关类完成了对配置文件的封装以后,就由XmlBeanDefinitionReader
进行读取和解析.对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
粗略时序图:继承
附上ClassPathXmlApplicatioContext
构造函数的源码:
public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, ApplicationContext parent) throws BeansException { super(parent); Assert.notNull(paths, "Path array must not be null"); Assert.notNull(clazz, "Class argument must not be null"); this.configResources = new Resource[paths.length]; //建立资源数组 private Resource[] configResources; for (int i = 0; i < paths.length; i++) { this.configResources[i] = new ClassPathResource(paths[i], clazz); } refresh(); //解析工做,ClassPathXmlApplicatioContext继承来自AbstractApplicationContext中的方法 }
首先,一样是封装配置文件,但封装完成以后并无直接进行读取,而是调用了refresh()
方法(这个方法里面进行了不少操做,扩展的功能几乎是在这里面实现的),refresh()
方法中的obtainFreshBeanFactory()
方法负责初始化BeanFactory
,并对XMl
文件读取,读取的核心实现是该方法中调用的refreshBeanFactory()
方法,这个方法再调用图中的loadBeanDefinitions(beanFactory)
方法(因为板面缘由,没有画出),而后在其中建立XmlBeanDefinitionReader
对象,再将最初封装的资源文件数组进行依次读取并解析.
两者在后面的Xml
解析工做都几乎是同样的,都采用了SAX
解析,区别就在于解析以前的准备和解析以后的完善工做.