Spring初级容器初始化:加载XML的Document

Spring是如何解析XML的呢?​

好了,我们接着方法doLoadBeanDefinitions继续分析:

我们可以看到,在方法doLoadBeanDefinitions中,首先将封装好的inputSource及资源resource传递进了doLoadDocument方法中,通过方法的名称应该是把resource资源加载成一个Document对象,确实我们也看到了它返回了一个Document对象。

到这个方法看下:

可以看到,XmlBeanDefinitionReader又将加载资源resource的任务,委托给了成员变量documentLoader来完成。那documentLoader又是什么呢?我们可以来看下这个成员变量:

可以看到,成员变量documentLoader的类型为DefaultDocumentLoader,通过类的名称,我们初步可以推测出它就是用来加载Document的一个组件。

loadDocument方法看一下。

看到这里几乎就真相大白了,Spring其实就是通过DOM来解析xml文件的

XML解析的示例:DOM解析

简单的实体 复制代码
package com.ruyuan.container;

public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
student.xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<students>
    <student>
        <name>tom</name>
        <age>17</age>
    </student>
</students>
获取Document 复制代码
public static Document getDocument(String xmlPath) throws Exception {
    try {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        return db.parse(xmlPath);
    } catch (Exception e) {
        throw new RuntimeException("文档解析失败...");
    }
}

首先,将xml文件的绝对路径,也就是xml文件在磁盘的位置,作为方法getDocument参数传递进去,然后通过DocumentBuilderFactory的newInstance方法,创建出一个DocumentBuilderFactory,再通过newDocumentBuilder方法得到DocumentBuilder对象。

可以看到,通过DocumentBuilder的parse方法解析xml文件,可以得到xml文件对应的Document对象,Document对象中就包含了student.xml中配置的所有信息。

方法getDocument暂时只是将指定路径下的xml文件加载成了Document对象,那具体如何解析Document对象,获取xml中配置的信息呢?我们再通过另外一个方法来解析下Document:

ini 复制代码
public static List<Student> getStudents(String xmlPath) throws Exception {
    // 1. 获取Document对象
    Document document = getDocument(xmlPath);

    // 2. 获取所有student节点
    List<Student> students = new ArrayList<>();
    NodeList studentNodes = document.getElementsByTagName("student");

    // 3. 遍历节点并解析数据
    for (int i = 0; i < studentNodes.getLength(); i++) {
        Element studentEle = (Element) studentNodes.item(i);
        Student student = new Student();
        student.setName(studentEle.getElementsByTagName("name")
                .item(0).getTextContent());
        student.setAge(Integer.parseInt(studentEle.getElementsByTagName("age")
                .item(0).getTextContent()));
        students.add(student);
    }

    // 4. 返回结果
    return students;
}

可以看到,在getStudents方法中,我们调用刚才的getDocument方法先获取student.xml对应的Document对象,然后获取配置文件中的所有student标签依次来遍历它们,通过对student标签的解析获取标签中name标签和age标签中的数据,并封装到Student对象中返回。最后,我们再测试下刚才写的这些方法:

相关推荐
Y***h1877 小时前
第二章 Spring中的Bean
java·后端·spring
稚辉君.MCA_P8_Java8 小时前
DeepSeek 插入排序
linux·后端·算法·架构·排序算法
t***p9358 小时前
idea创建SpringBoot自动创建Lombok无效果(解决)
spring boot·后端·intellij-idea
d***81728 小时前
解决SpringBoot项目启动错误:找不到或无法加载主类
java·spring boot·后端
无限大68 小时前
RBAC模型:像电影院选座一样管理权限,告别"一个用户配一个权限"的噩梦
后端
间彧8 小时前
在CI/CD流水线中如何集成自动化的发布验证和熔断机制?
后端
间彧8 小时前
如何处理蓝绿部署中的数据迁移和数据库版本兼容性问题?
后端
间彧8 小时前
什么是金丝雀/灰度发布
后端
间彧9 小时前
什么是蓝绿部署
后端
爷_9 小时前
Golang: sqlc 和 goose 最佳实践
后端·go·全栈