读取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"));

它包括以下几个问题:

  1. 怎么读取配置文件 获得IO资源
  2. 读取配置文件后,如何在Spring中以对象的形式进行封装
  3. 根据配置信息创建对象
  4. 所创建对象的生命周期
怎么读取配置文件 获得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的更多相关文章

  1. Spring源码分析(七)bean标签的解析及注册

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在上一篇中提到过Spring中的标签包括默认标签和自定义标签两种,而两种 ...

  2. Spring源码学习(2)——默认标签的解析

    上一篇随笔说到Spring对于默认标签和自定义标签的解析方法是不同的,这里详细看一下Spring对于默认标签的解析. private void parseDefaultElement(Element ...

  3. 如何将spring源码导入到eclipse中

    如何将spring源码导入到eclipse中 1. 下载spring源码  可以在github官网中找到spring源码来下载,或者直接通过git下载,是一样的,这里演示 直接在github网站下载, ...

  4. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  5. Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作

    写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...

  6. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  7. 从零开始学spring源码之xml解析(二):默认标签和自定义标签解析

    默认标签: 上一篇说到spring的默认标签和自定义标签,发现这里面东西还蛮多的.决定还是拆开来写.今天就来好好聊聊这两块是怎么玩的,首先我们先看看默认标签: private void parseDe ...

  8. 从零开始学spring源码之xml解析(一):入门

    谈到spring,首先想到的肯定是ioc,DI依赖注入,aop,但是其实很多人只是知道这些是spring核心概念,甚至不知道这些代表了什么意思,,作为一个java程序员,怎么能说自己对号称改变了jav ...

  9. 0源码基础学习Spring源码系列(一)——Bean注入流程

    作者:京东科技 韩国凯 通过本文,读者可以0源码基础的初步学习spring源码,并能够举一反三从此进入源码世界的大米! 由于是第一次阅读源码,文章之中难免存在一些问题,还望包涵指正! 一. @Auto ...

  10. Spring源码分析(十一)bean的加载

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 经过前面的分析,我们终于结束了对XML配置文件的解析,接下来将会面临更大 ...

随机推荐

  1. 火山引擎 ByteHouse:如何提升 18000 节点的 ClickHouse 可用性?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 ClickHouse 是业内被广泛使用的 OLAP 引擎.当集群规模过大时,ClickHouse 则面临使用局限性 ...

  2. 【Django-Vue】手机号是否存在接口 多方式登录接口 腾讯云短信介绍和申请 api与sdk

    目录 昨日回顾 今日内容 0 登录注册功能设计 1 短信登录接口 视图类 2 多方式密码登录接口 视图类 序列化类 路由 3 腾讯云短信介绍和申请 3.1api与sdk 补充 练习 昨日回顾 # 你的 ...

  3. C223 生产版本BAPI

    1.事务代码:C223 2.调用函数CM_FV_PROD_VERS_DB_UPDATE "-----------------------------@斌将军----------------- ...

  4. leaflet 绘制 点 线 面 圆 椭圆 线缓冲区

    leaflet有个绘图插件Leaflet.draw,但是我不想要它的控件,只想用它的绘制功能,控件我自己提供,当时不知道如何使用,就自己写了个绘制点线面圆和椭圆的工具,代码如下: /// <re ...

  5. POJ 3268 Silver Cow Party 题解 《挑战程序设计竞赛》

    POJ 3268 Silver Cow Party 奶牛派对:有分别来自 N 个农场的 N 头牛去农场 X 嗨皮,农场间由 M 条有向路径连接.每头牛来回都挑最短的路走,求它们走的路的最大长度? 们其 ...

  6. AnaConda 虚拟环境创建失败的解决方案

    问题:创建环境时,AnaConda界面下放一直显示正在创建中,然后过几分钟报错! 我的解决方法:--关闭 VPN... 其他解决方案请参考这篇文章:Here

  7. acwing算法提高课程笔记—数字三角形模型,最长上升子序列模型

    转自自网络,仅作为学习使用 1015摘花生 /*Hello Kitty想摘点花生送给她喜欢的米老鼠. 她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来. 地里每个道路的交叉点上都 ...

  8. L1-018 大笨钟 (10分)

    开始天梯赛专项训练 微博上有个自称"大笨钟V"的家伙,每天敲钟催促码农们爱惜身体早点睡觉.不过由于笨钟自己作息也不是很规律,所以敲钟并不定时.一般敲钟的点数是根据敲钟时间而定的,如 ...

  9. vivo 微服务 API 网关架构实践

    一.背景介绍 网关作为微服务生态中的重要一环,由于历史原因,中间件团队没有统一的微服务API网关,为此准备技术预研打造一个功能齐全.可用性高的业务网关. 二.技术选型 常见的开源网关按照语言分类有如下 ...

  10. <vue初体验> 基础知识 4、 vue的生命周期

    系列导航 <vue初体验> 一. vue的引入和使用体验 <vue初体验> 二. vue的列表展示 <vue初体验> 三. vue的计数器 <vue初体验&g ...