首页>>后端>>Spring->spring解析xml(spring解析xml工具)

spring解析xml(spring解析xml工具)

时间:2023-12-02 本站 点击:0

java 请问下SpringMVC中Spring是怎么去解析XML?

spring使用了jdk自带的jaxp解析技术,没有使用dom4j,所以spring工程里面也并没有依赖dom4j的jar。你可以看看XmlBeanDefinitionReader中的documentLoader属性,使用了DefaultDocumentLoader类来初始化的,DefaultDocumentLoader中的引用(import)都是JDK自带的类,DefaultDocumentLoader是spring用来解析xml的类。

Springboot自定义xml文件解析

有时候,要通过自定义XML配置文件来实现一些特定的功能。这里通过例子来说明。

首先,看部分spring加载bean文件的源码:

spring-beans-5.0.6.RELEASE.jar!/org/springframework/beans/factory/xml/PluggableSchemaResolver.class :

spring-beans-5.0.6.RELEASE.jar!/org/springframework/beans/factory/xml/DefaultNamespaceHandlerResolver.class :

可以看出,spring在加载xml文件的时候,会默认读取配置文件 META-INF/spring.schemas 和 META-INF/spring.handlers 。这样,我们就可以在这两个文件添加我们自定义的xml文件格式和xml文件解析处理器。

新建一个Springboot工程,pom如下。

SelfDefineXmlTrial/pom.xml :

然后,新建一个用于测试controller。

com.lfqy.springboot.selfdefxml.controller.SelfDefXmlController :

最后,创建一个Springboot的启动类。

com.lfqy.springboot.selfdefxml.SelfDefXmlApplication :

运行启动之后,浏览器访问 效果如下:

修改前面提到的配置文件 META-INF/spring.schemas 、 META-INF/spring.handlers ,添加xml格式说明。

META-INF/spring.schemas :

META-INF/spring.handlers :

添加xml格式说明配置文件。

META-INF/selfdef.xsd :

添加自定义xml格式处理器类。

com.lfqy.springboot.selfdefxml.selxmlparse.UserNamespaceHandler :

新增xml格式解析类。

com.lfqy.springboot.selfdefxml.selxmlparse.UserBeanDefinitionParser :

新增自定义xml对应的bean类。

com.lfqy.springboot.selfdefxml.beans.User :

添加自定义xml配置文件读取的相关逻辑。

com.lfqy.springboot.selfdefxml.SelfDefXmlApplication :

到这里,编码就完成了,工程的目录结构如下。

运行之后,控制台输出如下:

这里,通过实现一个启动时自动初始化的一个servlet来实现。

com.lfqy.springboot.selfdefxml.servlet.StartupServlet :

在启动时加载servlet,为了方便区分,这里新写一个启动类。

com.lfqy.springboot.selfdefxml.SelfDefXmlLoadOnStartupApplication

到这里,编码已经完成,工程的目录结构如下:

运行之后,控制台输出如下:

【Spring源码配置文件解析】2. xml注入配置信息 & @Value

这样xml中配置的bean的属性就会被注入配置文件里面对应的值

首先xml中的bean会在扫描的过程中封装成BeanDefinition对象,property标签会被弄成一个ProprotyValue的集合放在BeanDefinition的ProprotyValues变量中,所以在xml解析完成之后的BeanDefinition的ProprotyValues变量是这样的

上节PropertySourcesPlaceholderConfigurer这个类收集了environment配置信息和本地配置信息,并把它放在了PropertySourcesPropertyResolver的propertySources属性中

最后创建了一个StringValueResolver对象会调用PropertySourcesPropertyResolver来处理配置信息的替换

接下来就是取出所有的BeanDefinition,看看beanDefinition中的属性中是否有${}表达式,有的话就替换

很多的属性都可以用${}来引用配置信息

重点看看属性是如何被替换的

在BeanDefinitionVisitor.resolveValue方法中,String类型的走这

最终会调到PropertySourcesPlaceholderConfigurer创建的StringValueResolver匿名对象的实现方法中

这个匿名对象实现的方法又会调用PropertySourcesPropertyResolver来替换值,前面有提到所有的配置信息都在PropertySourcesPropertyResolver.propertySources中,那么接下来的工作就是从这个容器中找到对应的配置信息的key所对应的value

这里在入参时会创建一个PlaceholderResolver的匿名对象,实现的resolvePlaceholder方法将会调用PropertySourcesPropertyResolver.getPropertyAsRawString()

最后返回了被替换成对应配置信息的值

这里就会调用前面创建的匿名对象的实现方法,方法体重会调用调用PropertySourcesPropertyResolver.getPropertyAsRawString(),去用key获取对应的配置信息

PropertySourcesPropertyResolver.getPropertyAsRawString()

PropertiesPropertySource对象内部有name,和source,source是一个泛型,当前类型为Properties,PropertiesPropertySource需要实现getProperty方法,其实就是从source中获取属性值

最后调到了Properties类的get方法,返回value

对每个beanDefination都这样操作过一遍

注意这个StringValueResolver的resolveStringValue会调用PropertySourcesPropertyResolver的方法来处理配置信息的替换,PropertySourcesPropertyResolver持有了所有的配置信息。 那么后面@Value的解析也将StringValueResolver来完成

@Value的解析工作是在Bean实例化后,属性注入的时候从配置文件找出并设置进去的

populateBean方法

只有string类型的才能@Value注解,才需要处理

又是这个容器,之前PropertySourcesPlaceholderConfigurer的doProcessProperties放进去的StringValueResolver

最后又会回到这个地方解析并注入值,和xml方式获取配置信息是一样的

找到对应的配置信息之后,反射设置这个属性的值

如何使用spring解析xml文件

Spring框架从2.0版本开始,提供了基于Schema风格的XML扩展机制,允许开发者扩展最基本的spring配置文件(一般是classpath下的spring.xml)。试想一下,如果我们直接在spring.xml中加入一个自定义标签mytag id="aty"/matag,会发生什么呢?spring框架启动的时候会报错,因为spring根本不认识我们自定义的mytag,这样对spring.xml的校验就会失败,最终结果就是框架不能启动。有什么方法,能够让spring认识并加载解析我们自定义的mytag呢?这就是spring提供的xml扩展机制。我们可以在spring.xml中加入自己的标签,之后spring会帮我们解析并纳入自己的管理范围内,这也就是说我们扩展了spring的功能。

现在我们来看下怎么实现这个功能,可以参考spring帮助文档中的extensible-xml.html。我们知道如果在需要在spring.xml中配置数据源,需要进行如下的配置:

bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

property name="driverClassName" value="com.mysql.jdbc.Driver" /

property name="url" value="jdbc:mysql://localhost:3309/sampledb" /

property name="username" value="root" /

property name="password" value="1234" /

/bean


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Spring/9994.html