Spring XML 原理
现象
我们先给出一个简单的例子,看看 Spring 是如何解析 XML 取到定义的信息的
Student.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private int id;
private String name;
}
applicationContext.xml
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 文件 如何
我们带着以上三个问题来分析
1)我们通过 idea 点击 applicationContext.xml 中的 class 标签,能够跳转到 spring-beans.xsd 这个文件 ,可以很明显的发现,下面的 xsd 是对 applicationContext.xml 中定义的 bean 标签的限制和说明
spring-beans.xsd 的部分信息
...
2)我们已经找到 XML 的 xsd 文件,其作用是限制 XML 编写的规范。那 applicationContext.xml 和 spring-beans.xsd 是怎么关联的呢?我们在 applicationContext.xml 发现了一个定义
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
我们全局查找该字段,发现在
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 文件限制或校验的:
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.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 或许能简化我们对标签的定义。