写点什么

Spring XML 原理

用户头像
gin
关注
发布于: 4 小时前

现象

我们先给出一个简单的例子,看看 Spring 是如何解析 XML 取到定义的信息的

Student.java

@Data@AllArgsConstructor@NoArgsConstructor@ToStringpublic class Student {
private int id; private String name;}
复制代码

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:p="http://www.springframework.org/schema/p"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="studentA" class="com.gingo.training.camp.week05.course.aop.Student"> <property name="id" value="123"/> <property name="name" value="KK123"/> </bean>
<bean id="studentB" class="com.gingo.training.camp.week05.course.aop.Student" p:id="100" p:name="KK100"/></beans>
复制代码

XbeanTest

public class XbeanTest {    public static void main(String[] args) {        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");        Student studentA = applicationContext.getBean("studentA",Student.class);        System.out.println(studentA);    }}
复制代码

我们运行 main 方法,XML 中的定义的 Bean 被 spring 解析了,这个过程是如何发现的

分析

我们可以设想,要解析 XML 中的信息,大概需要两个步骤:

第一,限制,保证 XML 定义的信息是能被解析?,如定义 a 标签的值是 int 类型,所以 a 标签的值就不能是 String,否则提示报错。

第二,解析,哪个类来解析定义的 XML?

第三,XML 文件 如何 XML 的限制XML 的解析类 关联起来呢?

我们带着以上三个问题来分析

1)我们通过 idea 点击 applicationContext.xml 中的 class 标签,能够跳转到 spring-beans.xsd 这个文件 ,可以很明显的发现,下面的 xsd 是对 applicationContext.xml 中定义的 bean 标签的限制和说明

spring-beans.xsd 的部分信息

<xsd:attributeGroup name="beanAttributes">		<xsd:attribute name="name" type="xsd:string">			<xsd:annotation>				<xsd:documentation><![CDATA[	Can be used to create one or more aliases illegal in an (XML) id.	Multiple aliases can be separated by any number of spaces, commas,	or semi-colons (or indeed any mixture of the three).				]]></xsd:documentation>			</xsd:annotation>		</xsd:attribute>		<xsd:attribute name="class" type="xsd:string">			<xsd:annotation>				<xsd:documentation source="java:java.lang.Class"><![CDATA[	The fully qualified name of the bean's class, except if it serves only	as a parent definition for child bean definitions.				]]></xsd:documentation>			</xsd:annotation>		</xsd:attribute>  ... </xsd:attributeGroup>
复制代码

2)我们已经找到 XML 的 xsd 文件,其作用是限制 XML 编写的规范。那 applicationContext.xml 和 spring-beans.xsd 是怎么关联的呢?我们在 applicationContext.xml 发现了一个定义

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
复制代码

我们全局查找该字段,发现在 spring.schemas 文件中有定义内容如下

http\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsdhttps\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
复制代码

3)现在我们明白了 XML 文件是如何通过 xsd 文件限制或校验的:

  • XML 文件需要在头部引入校验某些标签的 schema,schema 通过 spring.schemas 绑定 xsd 文件,从而达到校验和限制的目的

4)那哪个类来解析 XML 中的标签呢,这个要分成两个部分

  • 原有的命名空间,如 Beans 下的命名空间 spring 通过 ClassPathXmlApplicationContext("applicationContext.xml") 我们传入的文件路径,找到 xml 文件进行解析(这个我们不展开,内容过多)

  • 自定义或者外部扩展命名空间,如 例子中 p 标签,就需要自己实现对该标签的解析了。其实 spring 已经帮我们实现了 p 命名空间的解析

5)打开 spring.handlers 文件,里面有 p 命名空间解析的处理类,SimplePropertyNamespaceHandler,当 xml 文件解析的是,判断标签是否是自定义或者外部命名空间(可以从 xml 中的 xmlns 区分),如果是就找到 spring.handlers 文件,获取能够解析该命名空间的标签。和 SPI 原理非常相似

http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandlerhttp\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandlerhttp\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
复制代码


6) 通过 spring.schemas 和 spring.handlers 就能自定义的标签解析器

总结

Tip:自定义标签的是非常复杂繁琐的,XmlBeans -> Spring-xbean 或许能简化我们对标签的定义。

用户头像

gin

关注

还未添加个人签名 2020.01.17 加入

真正的大师永远怀着一颗学徒的心

评论

发布
暂无评论
Spring XML 原理