当前位置: 首页 > 编程日记 > 正文

加载BeanFactory

前言

上一篇文章讲述了ApplicationContext扩展功能的之一:环境准备。这篇文章接着讲述ApplicationContext的扩展功能-----加载BeanFactory,也就是初始化BeanFactory,并进行XML文件的读取。

加载BeanFactory

obtainFreshBeanFactory方法从字面上的意思就是获取BeanFactory。之前说过,ApplicationContext是对BeanFactory的功能上的扩展,不但包含了BeanFactory的全部功能更在其基础上添加了大量的扩展应用,那么obtainFreshBeanFactory正是实现BeanFactory的地方,也就是经过了这个函数,ApplicationContext就已经拥有了BeanFactory的全部功能。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {//初始化beanFactory,并进行XML文件的读取,并将得到的BeanFactory记录在当前实体的属性中
        refreshBeanFactory();//返回当前实体的BeanFactory属性return getBeanFactory();}
protected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {//创建DefaultListableBeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();//为了序列化指定ID,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
            beanFactory.setSerializationId(getId());//定制BeanFactory,设置相关的属性,包括是否覆盖同名称的不同定义的对象以及循环依赖以及设置@Autowire和@Qualifier注解解析器
            customizeBeanFactory(beanFactory);//初始化DocumentReader,并进行XML文档的读取与解析
            loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}

我们来详细分析上面第二段代码的步骤:

(1)创建DefaultListableBeanFactory。

在介绍BeanFactory的时候,曾经提到过,声明方式为:BeanFactory bf = new XmlBeanFactory("spring.xml");,其中的XMLBeanFactory继承自DefaultListableBeanFactory,并提供了XmlBeanDefinitionReader类型的reader属性,也就是说DefaultListableBeanFactory是容器的基础。必须要首先实例化,那么在这里就是实例化DefaultListableBeanFactory的步骤。

(2)指定序列化id。

(3)定制BeanFactory。

(4)加载BeanDefinition。

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

因为DefaultListableBeanFactory类型的变量BeanFactory是函数类的局部变量,所以要使用全局变量记录解析结果。

接下来对上述的一些步骤进行详细的解析:

定制BeanFactory

这里已经开始了对BeanFactory的扩展,在基本容器的基础上,增加了是否允许覆盖是否允许扩展的设置并提供了注解@Qualifier和@Autowire的支持。

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);}}

上述代码对于允许覆盖和允许依赖的设置这里只是判断了是否为空,如果不为空要进行设置,但是并没有看到在那里进行设置,究竟这个设置是在那里进行设置的呢?还是那句话,使用子类覆盖方法,例如:

public class MyClassPathApplicationContext extends ClassPathXmlApplicationContext {@Overrideprotected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {super.setAllowBeanDefinitionOverriding(false);super.setAllowCircularReferences(false);super.customizeBeanFactory(beanFactory);}
}

 加载BeanDefinition

在上述代码的第一步中提到了将ClassPathXmlApplicationContext与XMLBeanFactory创建的对比,在实现配置文件的加载功能中除了我们第一步中已经初始化的DefaultListableBeanFactory外,还需要XmlBeanDefinitionReader来读取XML,那么在这个步骤中首先要做的就是初始化XmlBeanDefinitionReader。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {//为指定BeanFactory创建XmlBeanDefinitionReaderXmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// 对BeanDefinitionReader进行环境变量的设置beanDefinitionReader.setEnvironment(this.getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));//对BeanDefinitionReader进行设置,可以覆盖
        initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}

在初始化了DefaultListableBeanFactory和XmlBeanDefinitionReader后就可以进行配置文件的读取了。

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);}}

使用XmlBeanDefinitionReader的loadBeanDefinitions方法进行配置文件的加载及注册。这跟BeanFactory的套路是一致的。因为在XmlBeanDefinitionReader中已经将之前初始化的DefaultListableBeanFactory注册进去了,所以XmlBeanDefinitionReader所读取的BeanDefinitionHolder都会注册到DefaultListableBeanFactory中,也就是经过此步骤,类型DefaultListableBeanFactory的变量BeanFactory已经包含了所有解析好的配置。

 参考:《Spring源码深度解析》  郝佳 编著:

转载于:https://www.cnblogs.com/Joe-Go/p/10211289.html

相关文章:

t-top 命令详解

前言 展示操作系统进程信息。动态得,实时得展示正在运行的操作系统进程信息。 所显示的系统摘要信息的类型以及为进程显示的信息的类型,顺序和大小都是用户可配置的,并且可以使配置在重新启动后保持不变。该程序为流程操作提供了一个有限的交…

怎么看懂c语言程序,求讲解一下这个程序,我看了1个小时都没有看懂,

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼# include #define N 9void fun(int a[], int n){ int i,j, max, min, px, pn, t;for (i0; i{/**********found**********/max min ___a[i]__;px pn i;for (ji1; j/**********found**********/if (max<___a>{ max a[j];…

【转】Winform输入法控制

来源&#xff1a;http://blog.itpub.net/23109131/viewspace-630576 想实现输入法切换&#xff1a;思路&#xff0c;找出当前系统所有输入法总个数&#xff0c;当前输入法在总输入法中的索引&#xff0c;通过改变索引值&#xff0c;来切换输入法 void input() {//变全角为半角的…

vector与结构体联合使用 在磁盘中生成.txt 文件

一下纯属个人总结、欢迎拍砖&#xff01;谢谢 我意思到以练促进学习C编程基础是很有帮助的 这篇文章是我为了熟悉掌握文件流和STL中的vector以及结构体三个只知识点所写的代码&#xff1a; #include <string> #include <stdlib.h> #include <iostream> #incl…

SQL Server 2008 R2如何开启数据库的远程连接

SQL Server 2008 R2如何开启数据库的远程连接 转载于:https://www.cnblogs.com/macT/p/10213025.html

二分法:二分查找(递归+非递归)实现

二分查找又称折半查找&#xff0c;首先&#xff0c;假设表中元素是按升序排列&#xff0c;将 表中间位置的关键字与查找关键字比较: 如果两者相等&#xff0c;则查找成功;否则利用中间位置将表分成前、后两个子表: 1)如果中间位置的关键字大于查找关键字&#xff0c;则进一步查…

mongodb数据库的一些常用命令列表

超级用户相关&#xff1a;use admin#增加或修改用户密码db.addUser(ixigua,pwd)#查看用户列表db.system.users.find()#用户认证db.auth(ixigua,pwd)#删除用户db.removeUser(mongodb)#查看所有用户show users#查看所有数据库show dbs#查看所有的collectionshow collections#查看…

c语言函数库哪里keyk,[精品]C语言库函数(字母G-K)-教案.doc

[精品]C语言库函数(字母G-K)-教案C语言库函数(字母G-K)- -??????????????????????????????????????(G类字母) - 1函数名: gcvt 功 能: 把浮点数转换成字符串 用 法: char *gcvt(double value, int ndigit, char *buf); 程序例: #include…

超链接调用js函数

<a href"javascript:gouwu()" ><span class"Buy" id"buyButton"></span></a>超链接调用js前面要加javascript:****************************SuppressWarningsJ2SE 提供的最后一个批注是 SuppressWarnings。该批注的作用…

iOS 轻击、触摸和手势的检测

一、检测捏合手势( UIPinchGestureRecognizer): //设定一个实例变量存储手指之间的其起始距离 property (assign, nonatomic) CGFloat initialFontSize;//调用&#xff1a;UIPinchGestureRecognizer *pinch [[UIPinchGestureRecognizeralloc]initWithTarget:selfaction:select…

二分法:search insert position 插入位置

问题描述&#xff1a; 给定一个排序数组nums(无重复元素)与目标值target&#xff0c;如果target在nums里 出现&#xff0c;则返回target所在下标&#xff0c;如果target在nums里未出现&#xff0c;则返回target应该 插入位置的数组下标&#xff0c;使得将target插入数组nums后&…

c语言课程设计学生籍贯信息记录簿,C语言课程设计 学生籍贯信息记录簿设计.doc...

C语言与程序设计课程设计学生籍贯信息记录簿设计学 院 信息工程班 级 物联1301班学 号 131408119姓 名 滕玲一&#xff0e;设计目的该软件主要是编辑一个学生籍贯信息记录簿记录每个学生信息&#xff0c;包括&#xff1a;学号、姓名、籍贯。具体功能&#xff1a;1.创建信息链表…

SharePoint使用BCS开发你第一个应用程序(三)

SharePoint使用BCS开发你第一个应用程序&#xff08;三&#xff09; 创建外部内容类型。 创建外部内容类型有三种不同方式&#xff1a;1. 在记事本上手写XML代码&#xff08;不推荐&#xff09;。2. 使用SharePoint Designer 2010 创建&#xff08;推荐&#xff09;。3. 使用VS…

Java Coverage(Cobertura)工具

首先是下载Cobertura的jar包了&#xff0c;这个工具底层是JCoverage&#xff0c;熟悉Jcoverage的对这个也不会陌生的。 Cobertura官网 http://cobertura.sourceforge.net/ 大家可以了解很多东西&#xff0c;比如现在的作者啊什么&#xff0c;这里就不介绍了 然后点Download&…

Java 内部类及其原理

Java中实现内部类 内部类相信大家都用过很多次了&#xff0c;就不说它是怎么用的了。 内部类 1.成员内部类 需要注意的是&#xff0c; 当成员内部类拥有和外部类同名的成员变量或这方法时&#xff0c; 默认情况下访问的是内部类的成员&#xff0c; 如要访问外部类的同名成员&am…

二分法:查找区间search for a range

问题描述&#xff1a; 给定一个排序数组nums(nums中有重复元素)与目标值target&#xff0c;如果 target在nums里出现&#xff0c;则返回target所在区间的左右端点下标&#xff0c;[左端点, 右端点]&#xff0c;如果target在nums里未出现&#xff0c;则返回[-1, -1]。 例如: ar…

c语言向表格内存入数据,怎么实现横向到存入多个单元格,在列数固定的报表中逐格横向填充数据并折行...

在很多需要打印的报表中&#xff0c;受限于纸张的大小&#xff0c;往往会限制行数或者固定列数。我们在《单据类报表的制作》一文中&#xff0c;曾经介绍了限制了行数的情况如何实现&#xff0c;现在&#xff0c;我们再来看一下&#xff0c;在固定了列数的情况下&#xff0c;如…

设计模式之简单工厂模式

一、概述 工厂模式具体包括了简单工厂、工厂方法、抽象工厂&#xff0c;它们是按照从简单到复杂的顺序排列的&#xff0c;属于设计模式中的创建型&#xff0c;其中简单工厂并不属于GOF的23中模式。 但是它是理解其它的工厂模式的一个很好的基础&#xff0c;所以很多人在讲述设…

zendserver的版本是怎么回事?免费版哪里去了?

zend server 的版本&#xff0c;官网上说是四个版本&#xff0c;免费版、小企业版、专业版、企业版。 但下载只有一个版本。在下载的页面中大大的free download 很是显眼。安装完成之后显示为企业版。使用几天之后&#xff0c;显示你的许可即将到期。 输入密码&#xff0c;登录…

sql-case when 条件1 then 取值1 when 条件2 then 取值2 else 取值3 end

遇到 XXX情况 就 XXX 遇不到就 XXX 结束case when …… then …… else …… end 例如一个3条件取值的字段&#xff1a; case when 条件1 then 取值1 when 条件2 then 取值2 else 取值3 end when后接条件语句&#xff0c;then后为字段取值&#xff08;数值或字符串等都可以&…

二叉树:二叉搜索树的创建和插入

二叉搜索树又名二叉排序树。 大概简略的思维导图如下&#xff0c;方便记忆特性 基本二叉搜索树创建过程如下 /*数据结构如下*/ typedef struct tree {int data;struct tree *left NULL;struct tree *right NULL; }Tree,*TreeNode;/*Node 为二叉树根节点&#xff0c;insert…

ie7和ie8 select使用jquery clone不兼容处理

本文解决方案基于http://blog.csdn.net/zzx3q/article/details/8017794 在ie7和ie8下&#xff0c;用jquery clone复制一个select&#xff0c;复制的select是本体的select初始化时的一个副本&#xff0c;无法复制目前本体select选择。 解决方案&#xff1a; <!DOCTYPE html&g…

c语言中floox的头文件,PC-1211袖珍计算机在合成氨厂生产中的应用 第五讲 循环语句(FOR-NEXT语句)...

PC-1211袖珍计算机在合成氨厂生产中的应用 第五讲 循环语句(FOR-NEXT语句)在化工生产中为了分析两个或两个以上参数对生产的影响往往需要进行某些有规律的重复计算。这些计算在程序中可以用赋值语句或条件语句来实现,但从下面的介绍可以看出,这时若采用循(本文共7页)阅读全文&g…

C#Winform+WindowsAPI做个剪贴板无缝自动保存器(视频截图利器)

C#WinformWindowsAPI做个剪贴板无缝自动保存器&#xff08;视频截图利器&#xff09; (本文最新代码已上传到GitHub&#xff0c;地址在&#xff08;https://github.com/bitzhuwei/ClipboardImageSaver&#xff09;) 利用C#和Window API做了个自动保存剪贴板内的图片的工具&…

Kafka配置SASL/PLAIN认证

1、安装zk&#xff0c;kafka 2、配置server.properties security.inter.broker.protocolSASL_PLAINTEXT sasl.mechanism.inter.broker.protocolPLAIN sasl.enabled.mechanismsPLAIN listenersSASL_PLAINTEXT://0.0.0.0:9092 advertised.listenersSASL_PLAINTEXT://host:9092 3…

二叉树:二叉搜索树的编码和解码

二叉搜索树的编码和解码描述&#xff1a; 编码&#xff1a;即将一个二叉搜索树编码&#xff0c;节点数值转换为字符串 解码&#xff1a;即将一个字符串解码&#xff0c;数值转换为对应的二叉搜索树的节点 过程导图如下&#xff1a; 针对性编码实现如下: /*数字转字符串*/ vo…

springmvc3.2+spring+hibernate4全注解方式整合(一)

<?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xmlns:web"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&…

c 应用程序多语言版本,c – 在win32 API应用程序中实现全球化/多语言功能

Windows上多语言应用程序的基础是使用“资源”.资源是附加在可执行文件末尾的块,它只包含数据,并以非常特定的方式格式化,以便Windows能够解释这些数据.在资源中,您可以找到对话框,字符串表以及版本信息(在资源管理器中文件的属性对话框中显示的信息).您可以通过在Visual C中打…

整数展示分数和整形数的四则运算

文章结束给大家来个序程员笑话&#xff1a;[M] /* * Copyright (c) 2013, 烟台大学计算机学院 * All rights reserved. * 文件名称&#xff1a;test.cpp * 作者&#xff1a;邱学伟 * 成完日期&#xff1a;2013 年 5 月 4 日 * 版本号&#xff1a;v1.0 * 输入描述&#xff1a;无…

二叉树:二叉搜索树实现 逆序数问题

关于逆序数的问题描述如下&#xff1a; 已知数组nums&#xff0c;求新数组count&#xff0c;count[i]代表了在nums[i]右侧且比 nums[i]小的元素个数。 例如: nums [5, 2, 6, 1], count [2, 1, 1, 0]; nums [6, 6, 6, 1, 1, 1], count [3, 3, 3, 0, 0, 0]; nums [5, -7, 9…