Spring源码之XML文件中Bean标签的解析1
读取XML文件,创建对象
xml文件里包含Bean的信息,为了避免多次IO,需要一次性读取xml文件中所有bean信息,加入到Spring工厂。
读取配置文件
new ClassPathResource("applicationContext.xml")
ClassPathResource是Spring封装的一个类型;

Resource接口 :可以读取相关资源文件的内容 获得输入流;可读取的类型,不仅包括本地的xml、 properties、txt 等文件,还包括 网络中的资源。它有父接口,InputStreamSource,其中定义了一个getInputStream方法,用来获取输入流。
ClassPathResource类中对getInputStream方法的实现。

Resource将xml配置文件读取到jvm中,那jvm中是如何体现xml中的bean呢?
因为一切皆对象,所以肯定是以对象的方式存在的。标签就会以BeanDefinition对象的方式存在于jvm中。
Spring通过SAX的技术手段,对xml解析,封装BeanDefiniton。
IOC的核心
下方代码所代表的含义,实际上就是IOC的核心:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
它包括以下几个问题:
- 怎么读取配置文件 获得IO资源
- 读取配置文件后,如何在Spring中以对象的形式进行封装
- 根据配置信息创建对象
- 所创建对象的生命周期
怎么读取配置文件 获得IO资源
通过Resource接口的实现类,比如ClassPathResource,得到InputStream。
读取配置文件后,如何在Spring中以对象的形式进行封装
以BeanDefinition的形式存在,用的最多的实现类是GenericBeanDefinition。

Spring底层如何通过读取 XML 封装成BeanDefinition呢
使用XmlBeanFactory中的XmlBeanDefinitionReader对象的方法。

Spring标识XmlBeanFactory过期了,可以用以下代码替换:
DefaultListableBeanFactory beanFactory1 = new DefaultListableBeanFactory();
Resource resource = new ClassPathResource("applicationContext.xml");
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory1);
xmlBeanDefinitionReader.loadBeanDefinitions(resource);
Object product1 = beanFactory1.getBean("product");
System.out.println("product1 = " + product1);
但是比较繁琐,我们分析源码还是使用XmlBeanFactory来分析。
Spring底层如何做到通过XmlBeanDefinitionReader读取 XML封装成BeanDefinition呢?

Spring允许在一个工程中有多个Spring工厂同时出现 ,但是情况非常少见 。
比如SpringMVC中 父子容器
DispatcherServlet ---- childFactory
ContextLoaderListener ---- rootFactory

InputStream inputStream = encodedResource.getResource().getInputStream();
这行代码是封装成SAX的InputStream类型,对xml进行解析。
最主要的就是return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
来加载BeanDefinition。

Document doc = doLoadDocument(inputSource, resource);
这行代码得到的还是XML解析封装的对象。
int count = registerBeanDefinitions(doc, resource);
这行代码就是注册BeanDefinition的方法,并返回注册的数量。



parseDefaultElement(ele, delegate);用来解析基本标签
比如:
<bean id="" class="" scope="" parent="" init-method=""
<property name value
</bean>
<bean id="" class="" scope="" parent="" init-method=""
<construt-arg>
</bean>
delegate.parseCustomElement(ele);解析自定义标签
比如:
<context:propertyplace-holder
<context:component-scan
..
<tx:annotation-driven
<mvc:annotation-drvent
<aop:config
我们目前看基本标签的解析;

import标签
可以引入其他的配置文件
<import resource="applicationContext1.xml"/>
<import resource="applicationContext2.xml"/>
<import resource="applicationContext3.xml"/>
alias标签
别名
<bean id="product" name= "p" class="xxxx.xxx.Product"/>
name代表别名
也可以这样写
<bean id="user" class="xxxx.xxx.User"/>
<alias name="user" alias="u"/>
alias标签也可以写别名
beans标签上文已经讲过
bean标签——用的最多,着重分析

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
解析标签里的元素,封装成BeanDefinitionHolder
(对BeanDefinition做了一层包装)
其中有三个属性
private final BeanDefinition beanDefinition;
存储BeanDefinition private final String beanName;
存储id值,如果没有id,就是name值
如果也没有name,会自动生成一个 private final String[] aliases;
存储别名 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
如果有自定义标签,再解析自定义标签 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
将BeanDefinition,以id为key存储到map中 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
发送注册完成的事件;此方法是空实现,可以自己实现
parseBeanDefinitionElement重载1
此方法用来解析id、别名,判断id是否唯一、调用parseBeanDefinitionElement重载2;若id,name都没有,生成id等操作。

parseBeanDefinitionElement重载2
此方法用来解析class标签,创建BeanDefinition、解析scope、abstract标签等。

Spring源码之XML文件中Bean标签的解析1的更多相关文章
- Spring源码分析(七)bean标签的解析及注册
摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在上一篇中提到过Spring中的标签包括默认标签和自定义标签两种,而两种 ...
- Spring源码学习(2)——默认标签的解析
上一篇随笔说到Spring对于默认标签和自定义标签的解析方法是不同的,这里详细看一下Spring对于默认标签的解析. private void parseDefaultElement(Element ...
- 如何将spring源码导入到eclipse中
如何将spring源码导入到eclipse中 1. 下载spring源码 可以在github官网中找到spring源码来下载,或者直接通过git下载,是一样的,这里演示 直接在github网站下载, ...
- Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签
写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...
- Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作
写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...
- 从零开始学spring源码之xml解析(二):默认标签和自定义标签解析
默认标签: 上一篇说到spring的默认标签和自定义标签,发现这里面东西还蛮多的.决定还是拆开来写.今天就来好好聊聊这两块是怎么玩的,首先我们先看看默认标签: private void parseDe ...
- 从零开始学spring源码之xml解析(一):入门
谈到spring,首先想到的肯定是ioc,DI依赖注入,aop,但是其实很多人只是知道这些是spring核心概念,甚至不知道这些代表了什么意思,,作为一个java程序员,怎么能说自己对号称改变了jav ...
- 0源码基础学习Spring源码系列(一)——Bean注入流程
作者:京东科技 韩国凯 通过本文,读者可以0源码基础的初步学习spring源码,并能够举一反三从此进入源码世界的大米! 由于是第一次阅读源码,文章之中难免存在一些问题,还望包涵指正! 一. @Auto ...
- Spring源码分析(十一)bean的加载
摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 经过前面的分析,我们终于结束了对XML配置文件的解析,接下来将会面临更大 ...
随机推荐
- FTP 被动模式配置
总结:FTP 21端口,可以主动连接,防火墙配置一下21端口放行就OK了.非21端口,需要设成被动连接和端口范围.防火墙要做相应的配置 原理 https://www.cnblogs.com/zjoch ...
- 【C++开源库】Windows 下编译 libcurl 库
亲测可用: https://codeantenna.com/a/pJaN3omqjp What is libcurl ? libcurl 是一个跨平台的网络协议库,支持 http, https, ft ...
- Codeforces Round #620 (Div. 2) (A~D)
比赛链接:Here A题挺水的就不写了 1304B - Longest Palindrome 题意: 输入 \(m\) 个长度为 \(n\) 的字符串,问这些字符串能组成的最长回文串有多长. 思路: ...
- 三、redis集群搭建
系列导航 一.redis单例安装(linux) 二.redis主从环境搭建 三.redis集群搭建 四.redis增加密码验证 五.java操作redis 环境:centos7需要的安装包: redi ...
- Linux 系统安全加固经验总结
本文为博主原创,转载请注明出处: 目录 1. 禁止root密码登录 2. linux 用户密钥复杂度及有效期设置 3. 检查sudo权限 4.关闭ftp 5.设置文件的属主并指定读写执行权限 6.管 ...
- mysql 主从状态查询及恢复
转载请注明出处: 备机执行主备恢复的命令: 今天早上打开电脑,验证测试环境的服务时,发现服务挂了,当登录服务器查看日志的时候,发现数据库连不上了,紧忙登上数据库服务器,发现数据库mysql 的服务挂了 ...
- SpringCloud对使用者透明的数据同步组件
一.背景 云端使用Spring Cloud实现,A服务有一些数据,B和C服务也需要A服务的这些数据,但是系统上面只有A服务有数据操作的入口,B和C服务只能从A服务处同步数据到自己的表里面. 解决方案是 ...
- 宝塔部署 springboot 项目遇到的 一些bug处理方案
1,上传的项目(jar包)的数据库用户名 .密码 , 和服务器的数据库用户名.密码不一致 2,数据库的表结构没有创建 3, 宝塔 phpmyadmin 进不去 原因: 服务器没有放行888端口, 宝塔 ...
- [转帖]查询 HTTPS 网站 TLS 版本
参考 检查网站的TLS版本 – wentao's blog Linux curl 命令详解 - 腾讯云开发者社区-腾讯云 TLS 版本查询_天泽岁月的博客-CSDN博客_查看tls版本 使用 Open ...
- Nginx reload重新加载配置文件的异常情况
Nginx reload重新加载配置文件的异常情况 背景 临近年底, 很多业务工作量都上来了. 今天同事告知, nginx的log 里面出现了大量的 too many openfiles 的提示信息. ...