1.前言

我们用SpringMVC的时候一般会用到Xml配置文件,那么我们这篇文章就来谈下Spring读取Xml配置文件的一些关键实现点。

2.AbstractRefreshableApplicationContext

这个抽象类的名称告诉我们这是一个具备可刷新能力的应用上下文,并且里面定义了一个关键接口loadBeanDefinitions

/**     * Load bean definitions into the given bean factory, typically through     * delegating to one or more bean definition readers.     * @param beanFactory the bean factory to load bean definitions into     * @throws BeansException if parsing of the bean definitions failed     * @throws IOException if loading of bean definition files failed     * @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader     */protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)throws BeansException, IOException;

我们从这个接口名称就可以看出是用来加载BeanDefinition的,并且参数传入了一个很重要的东西BeanFactory,那么这个接口由谁来实现了呢?

2.AbstractXmlApplicationContext

    /**     * Loads the bean definitions via an XmlBeanDefinitionReader.     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader     * @see #initBeanDefinitionReader     * @see #loadBeanDefinitions     *///todo 重载了 AbstractRefreshableApplicationContext@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.

//todo 传入bean工厂 使得beanDefinitionReader有了 Environment  2020-09-11//todo 使得beanDefinitionReader有了 BeanRegistry  2020-09-11        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

// Configure the bean definition reader with this context's// resource loading environment.//todo  beanDefinitionReader 又设置了 Environment 把当前Context的环境 给了他  2020-09-11        beanDefinitionReader.setEnvironment(this.getEnvironment());

//todo important 设置为ClassPathXmlApplicationContext 又因为AbstractApplicationContext继承自 DefaultResourceLoader 为自己 2020-08-31        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.//初始化beanReader        initBeanDefinitionReader(beanDefinitionReader);//加载bean定义        loadBeanDefinitions(beanDefinitionReader);    }

这个loadBeanDefinitions接口的实现做了几件事情,我们来分析下:1.每次调用都会实例化一个XmlBeanDefinitionReader对象,并且把接口的参数beanFactory都放入了它的构造函数。我们看XmlBeanDefinitionReader类的构造函数实际上是接收一个BeanDefinitionRegistry接口的,也就是说DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,这个实现就为之后解析Bean配置并且用通过这个registry注册BeanDefinition提供了可能。至于BeanDefinitionRegistry接口我们可以之后单独写文来分析,在这里就不展开讨论。2.把当前应用上下文的Envrionment环境给了XmlBeanDefinitionReader,这点也很重要,我们还记得可以在Xml配置文件中定义bean的profile配置来开发环境来筛选吗?我们来截张图:看红圈圈出来的地方,beanDefinitionReader.setEnvironment就让这个功能实现得到了基础保障,因为我们肯定首先要有应用上下文的环境嘛,具体这个profile小配置的解析之后我们用个简短的小文章来揭秘下。3.设置了beanDefinitionReader的ResourceLoader为当前应用上下文。4.设置了entityResolver,先不管。5.初始化了beanDefinitionReader,默认设置了下验证模式,先不用管。6.开始加载beanDefinitions,很重要。

最后一步最终调用到了beanDefinitionReader的registerBeanDefinitions这个方法。

3.XmlBeanDefinitionReader

/**     * Register the bean definitions contained in the given DOM document.     * Called by {@code loadBeanDefinitions}.     * 

Creates a new instance of the parser class and invokes
* {

@code registerBeanDefinitions} on it.
* @param doc the DOM document
* @param resource the resource descriptor (for context information)
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of parsing errors
* @see #loadBeanDefinitions
* @see #setDocumentReaderClass
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
*/
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {

//默认是DefaultBeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
//https://www.cnblogs.com/whx7762/p/7777775.html
//todo 里面最终调用了registry.registerBeanDefinition 2020-08-31
//todo createReaderContext new 一个XmlReaderContext 构造函数会传入 当前 XmlBeanDefinitionReader(继承自 AbstractBeanDefinitionReader 实现了 EnvironmentCapable 接口) 所以有了 Environment 2020-10-18
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}

  1. 每次调用都会创建一个BeanDefinitionDocumentReader对象,默认就是在XmlBeanDefinitionReader中定义好的DefaultBeanDefinitionDocumentReader类。

  2. 获取registry中的BeanDefinition数量。

  3. 来来来!最重要一步就是通过创建的documentReader对象来注册beanDefinition了,传入了要解析的文档, 创建带有resource资源的readerContext给到我们的documentReader对象。

  4. 返回注册过后当前的beanDefinitionCount。

spring bean xml 调用方法_Spring通过Xml方式注册Bean的几处关键实现点相关推荐

  1. Vue组件之间传值/调用方法的几种方式

    组件之间传值/调用方法的几种方式 (一)父组件向子组件传值==props 1.在父组件中使用子组件的地方绑定数据 <children :message="message"&g ...

  2. java远程插件动态注册机制_Spring运行时动态注册bean的方法

    在spring运行时,动态的添加bean,dapeng框架在解析xml的字段时,使用到了动态注册,注册了一个实现了FactoryBean类! 定义一个没有被Spring管理的Controller pu ...

  3. python读取xml标注坐标_遍历文件 创建XML对象 方法 python解析XML文件 提取坐标计存入文件...

    XML文件??? xml即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 里面的标签都是可以随心所欲的按照他的命名规则来定义的,文件名为roi.xm ...

  4. java xml读取方法_Java读取XML文件的方法

    Java读取XML文件的方法 发布时间:2020-08-19 14:39:08 来源:亿速云 阅读:63 作者:小新 这篇文章主要介绍了Java读取XML文件的方法,具有一定借鉴价值,需要的朋友可以参 ...

  5. jsf xhtml调用方法_JSF的工作方式以及调试方法–可以使用polyglot吗?

    jsf xhtml调用方法 JSF不是我们通常认为的那样. 这也是一个调试起来可能有些棘手的框架,尤其是在初次遇到时. 在这篇文章中,让我们继续探讨为什么会出现这种情况,并提供一些JSF调试技术. 我 ...

  6. @Bean修饰的方法参数的注入方式

    方法参数默认注入方式为Autowired,即先根据类型匹配,若有多个在根据名称进行匹配. 1:复杂类型可以通过@Qualifier(value="XXX")限定; 2:对于普通类型 ...

  7. Java进阶(5)——调用方法的三种方式

    JAVA中调用方法的方式有三种 1.通过new对象,调用构造方法 2.通过对象.方法名,调用非静态方法 3.通过类名.方法名,调用静态方法 具体看一下下面的实例 public class interf ...

  8. Java中调用方法的几种方式

    一般的,在Java语言中,调用方法有三种方式. 第一种:通过对象名.方法名进行调用,这是最普通的也是最常见的一种调用方式. 第二种:通过new关键字调用构造方法,这种是在实例化对象时使用的方式. 第三 ...

  9. Spring - BeanDefinitionRegistryPostProcessor 扩展接口 动态注册bean

    文章目录 Pre org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor 接口的继承关系 BeanD ...

最新文章

  1. C五:exit()函数作用的程序
  2. @jsonfield注解_好了,不装了,撸个注解有什么难的!
  3. php计算经纬度距离,php经纬度计算距离
  4. 分别用函数和带参的宏,从三个数中找出最大的数。
  5. 6*6行列式相加的c语言,求行列式的值,用C语言怎么写啊?
  6. linux6.5配置ssh,CentOS 6.5 配置 SSH 免密登录
  7. FFmpeg学习(6)——视频拼接
  8. android-ImageView显示选择本地图片或拍照
  9. 系统集成项目管理工程师2022年上半年广东卷下午案例分析题及答案
  10. 一个开源的音频分离深度学习项目
  11. 南京邮电大学计算机专业学费多少,南京邮电大学学费多少
  12. ETL工具kettle实现数据同步
  13. Linux系统中使用Xbox360手柄
  14. 同表父子关系 的SQL查询语句的写法
  15. 2020年计算机系毕业人数,2020年中国大学生各专业就业报告出炉:计算机类专业月薪最高!...
  16. wma格式怎么转换mp3,4种方法超快学
  17. 华为路由器交换机快捷键大全
  18. JAVA图片裁剪工具类
  19. 申请美国大学计算机专业,美国大学计算机专业申请
  20. 伴风网易博客linux,推开窗,让春色伴随你我

热门文章

  1. 为Jupyter notebook配置R kernel过程及踩坑记录
  2. t检验特征筛选详解及实战
  3. 服务器到底长什么样子啊(#゚Д゚)?
  4. Java程序设计-基础知识
  5. python3环境搭建(利用Anaconda+pycharm+pytorch)
  6. oracle 257,ORACLE 10g SYSAUX表空间快速增长之WRH$_ACTIVE_SESSION_HISTORY篇
  7. python随机选取列表中的一个字符串_如何从Python中的列表中选择随机字符串?
  8. linux 卡在grub_安装Linux系统,Ubuntu时卡在这个界面不动了,有3个小时了。。显示:“正在运行update_grub”......
  9. jupyter notebook 插入图片
  10. 2.Java中String,StringBuilder以及StringBuffer的关系与区别