创建ApplicationContext与BeanFactory时的区别-Spring源码学习之容器的基本实现
可以加载XML两种方法
使用 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
.
不同点
BeanFactory
是延迟加载,如果一个Bean
当中存在属性没有加载,会在第一次调用getBean()
方法的时候报错,而ApplicationContext
会在读取Xml
文件后,如果配置文件没有错误,就会将所有的Bean
加载到内存中,缺点就是在Bean
较多的时候比较占内存,程序启动较慢.
Spring
容器加载中最重要的两个类
DefaultListableBeanFactory
XmlBeanFactory
继承自DefaultListableBeanFactory
,而后者是整个Bean
加载的核心部分,是Spring
注册及加载Bean
的默认实现,而XmlBeanFactory
使用了自定义的Xml
读取器XmlBeanDefinitionReader
,实现了个性化的BeanDefinitionReader
读取.
XmlBeanDefinitionReader
主要负责Xml
文件的读取、解析和注册功能
加载时的区别
上面的两种方法的处理大致相同,让我们通过时序图看看两者在加载时的区别:
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicaitonContext.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
解析,区别就在于解析之前的准备和解析之后的完善工作.
创建ApplicationContext与BeanFactory时的区别-Spring源码学习之容器的基本实现的更多相关文章
- Spring源码学习之容器的基本实现(一)
前言 最近学习了<<Spring源码深度解析>>受益匪浅,本博客是对学习内容的一个总结.分享,方便日后自己复习或与一同学习的小伙伴一起探讨之用. 建议与源码配合使用,效果更嘉, ...
- spring源码学习之容器的基本实现
最近想拿出一部分时间来学习一下spring的源码,还特意买了一本书结合来看,当然主要是学习并跟着作者的思路来踏上学习spring的源码的道路,特意在此记录一下,<spring源码深度解析> ...
- spring源码学习之容器的扩展(二)
六 BeanFactory的后处理BeanFactory作为spring容器的基础,用于存放所有已经加载的bean,为了保证程序上的高扩展性,spring针对BeanFactory做了大量的扩展,比如 ...
- spring源码学习之容器的扩展(一)
在前面的章节,我们一直以BeanFactory接口以及它的默认实现XmlBeanFactory为例进行解析,但是,spring还提供了另一个接口ApplicationContext,用于扩展BeanF ...
- Spring 源码学习(一)-容器的基础结构
关注公众号,大家可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料 展示的代码摘取了一些核心方法,去掉一些默认设置和日志输出,还有大多数错误异常也去掉了,小伙伴想看详细代码 ...
- Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签
写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...
- Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md
写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...
- Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作
写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...
随机推荐
- 缓存算法(FIFO 、LRU、LFU三种算法的区别)
FIFO算法 FIFO 算法是一种比较容易实现的算法.它的思想是先进先出(FIFO,队列),这是最简单.最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小.空间满的时 ...
- 论文阅读:Deep Attentive Tracking via Reciprocative Learning
Deep Attentive Tracking via Reciprocative Learning 2018-11-14 13:30:36 Paper: https://arxiv.org/abs/ ...
- HTML基础【4】:表格标签
表格标签 在过去表格标签用的非常非常的多,绝大多数的网站都是使用表格标签来制作的,也就是说表格标签是一个时代的代表 作用:以表格形式将数据显示出来,当数据量非常大的时候,表格这种展现形式被认为是最为清 ...
- 关于ComponentOne For WinForm 的全新控件 – DataFilter数据切片器(Beta)
概述 数据切片器在电子商务网站上很常见 - 它们可以帮助用户快速过滤所选商品,并且所有过滤选项都可以在一个地方使用,通常包含核心控件类型为:清单,范围栏和单选按钮等.在ComponentOne For ...
- 【HNOI 2018】寻宝游戏
Problem Description 某大学每年都会有一次 \(Mystery\ Hunt\) 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为新 ...
- 20175317 《Java程序设计》第二周学习总结
20175317 <Java程序设计>第二周学习总结 教材学习内容总结 第二周我学习了教材三四章的内容,了解了Java与C语言的相似与不同之处. 其中第二章学到了标识符与关键字.基本数据类 ...
- JavaScript的DOM对象
HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HTML DOM 模型被构造为对象的树. HTML DOM 树 通过 ...
- django中邮件、日志的配置
邮件的发送及配置 # 配置邮件 EMAIL_USE_SSL = True EMAIL_HOST = 'smtp.qq.com' # 如果是 163 改成 smtp.163.com EMAIL_PORT ...
- linux 基础命令,未完待续
1, cd 进入系统根目录 cd / 进入当前用户的主目录 cd ~ 进入当前目录的上一级目录 cd .. 跳转到指定目录,从根目录开始 cd /apps/ 2, pwd 查看当前工作目录的完整路径 ...
- js中的setTimeout第三个参数
setTimeout跟setInterval大家应该都很熟悉的,但是一直很少注意,原来这两个函数可以支持第三个参数的,但是IE就呵呵了,仅IE(6-9)呵呵了,其他浏览器都支持的。 第三个参数将作为回 ...