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对象中返回。最后,我们再测试下刚才写的这些方法:

相关推荐
GetcharZp3 小时前
抛弃低效SSH!这套Ansible+Web可视化神器,让你天天准点下班!
后端
weixin_446260857 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
ttwuai8 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
用户8356290780518 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
用户9931441579848 小时前
微服务框架中获取用户信息
后端
xuanWb8 小时前
手写一个 LLM API 网关:Anthropic 与 OpenAI 协议转换的完整实现
后端
苍何8 小时前
给 Codex 换皮肤这门生意,被我开源了
后端
用户8356290780518 小时前
Python 实现 Excel 命名范围(Named Range)的创建与管理
后端·python
程序员David9 小时前
我让 Claude 从架构文档一路干到代码,踩了三个坑才摸清边界
后端