现象
我们先给出一个简单的例子,看看 Spring 是如何解析 XML 取到定义的信息的
Student.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public 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.xsd
https\://www.springframework.org/schema/beans/spring-beans-3.2.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
复制代码
3)现在我们明白了 XML 文件是如何通过 xsd 文件限制或校验的:
4)那哪个类来解析 XML 中的标签呢,这个要分成两个部分
5)打开 spring.handlers 文件,里面有 p 命名空间解析的处理类,SimplePropertyNamespaceHandler,当 xml 文件解析的是,判断标签是否是自定义或者外部命名空间(可以从 xml 中的 xmlns 区分),如果是就找到 spring.handlers 文件,获取能够解析该命名空间的标签。和 SPI 原理非常相似
http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
复制代码
6) 通过 spring.schemas 和 spring.handlers 就能自定义的标签解析器
总结
Tip:自定义标签的是非常复杂繁琐的,XmlBeans -> Spring-xbean 或许能简化我们对标签的定义。
评论