乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • XML 基础语法

    • XML 概述
    • XML 文档结构
    • XML 元素
    • XML 属性
    • XML 语法规则
    • XML 命名空间
    • XML 注释与处理指令
  • DTD 与文档验证

    • DTD 概述
    • DTD 元素声明
    • DTD 属性声明
    • DTD 实体声明
    • DTD 元素与属性对比
    • DTD 完整示例
  • XML Schema 定义

    • XML Schema 概述
    • XSD 简单类型
    • XSD 复杂类型
    • XSD 命名空间与引用
  • XPath 节点定位

    • XPath 概述
    • XPath 路径表达式
    • XPath 谓词与函数
  • XSLT 转换

    • XSLT 概述
    • XSLT 模板与匹配
    • XSLT 控制结构
    • XSLT 输出控制
  • XML 解析技术

    • XML 解析概述
    • DOM 解析
    • SAX 解析
    • StAX 解析
    • XML 与 Java — JAXP
  • XML 在 Java 中的应用

    • Spring XML 配置
    • MyBatis XML 映射
    • pom.xml 与 Maven
    • web.xml 配置详解
  • 现代数据格式对比

    • XML 与 JSON 对比
    • XML 与 YAML 对比
  • XML 显示与浏览器集成

    • XML 在浏览器中的显示
    • XMLHttpRequest 与 AJAX
    • 服务器端 XML 处理
  • XML 进阶查询与链接

    • XQuery 查询语言
    • XLink 超链接
    • XML 验证工具使用
  • XML Web 服务(选读)

    • XML Web 服务概述
    • SOAP 协议详解
    • WSDL 服务描述
    • RSS 内容聚合
    • RDF 资源描述框架

Spring XML 配置

本章定位 :掌握 Spring IoC 容器的 XML 配置方式——bean 定义、构造器注入、Setter 注入、命名空间扩展(c/p/util/context/aop)。

定义与作用

Spring Framework 虽然现在推荐注解和 Java Config,但 XML 配置是其 最经典 的 Bean 定义方式,也是理解 Spring IoC 原理的最佳切入点。

Spring XML 配置文件的核心作用:声明 Bean("你要管哪些对象")及其依赖关系("谁需要谁")。Spring 容器启动时读取 XML,使用反射创建对象并注入依赖,最终将所有 Bean 放入 ApplicationContext 中统一管理。

即使你主要用注解开发,理解 XML 配置仍然是必要的——很多遗留项目和维护文档中都使用 XML 配置。

核心原理:Spring IoC 容器从 XML 到 Bean

图解释 :Spring 容器通过 XmlBeanDefinitionReader 将 XML 转化为内部的 BeanDefinition 元数据,然后经历实例化→依赖注入→后处理的完整生命周期,最终存放到 ApplicationContext 中。

语法/结构要点

基础 bean 定义

<!-- 最简 Bean -->
<bean id="studentDao" class="com.feixiang.dao.StudentDao"/>

<!-- 通过构造器注入 -->
<bean id="studentService" class="com.feixiang.service.StudentService">
  <constructor-arg ref="studentDao"/>
  <constructor-arg value="乐途大学"/>
</bean>

<!-- 通过 Setter 注入 -->
<bean id="config" class="com.feixiang.config.AppConfig">
  <property name="maxStudents" value="100"/>
  <property name="dataSource" ref="dataSource"/>
</bean>

命名空间扩展

命名空间前缀典型用途
util<util:list>定义集合 Bean
context<context:component-scan>自动扫描 @Component
pp:name="value"简化 Setter 注入
cc:dao-ref="dao"简化构造器注入
aop<aop:config>AOP 配置

完整示例:白歌用 XML 配置教学管理系统

场景说明

飞翔科技的架构师 白歌 为教学管理系统编写 Spring XML 配置。系统包含:数据源、DAO 层、Service 层,使用构造器注入(强制依赖)和 Setter 注入(可选依赖)混合。

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd
         http://www.springframework.org/schema/util
         http://www.springframework.org/schema/util/spring-util.xsd">

  <!-- 启用注解的 Bean 后处理器 -->
  <context:annotation-config/>

  <!-- 数据源(使用属性占位符) -->
  <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/edu"/>
    <property name="username" value="root"/>
    <property name="password" value="dev123"/>
  </bean>

  <!-- DAO 层:无依赖 -->
  <bean id="studentDao" class="com.feixiang.edu.dao.StudentDao">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <bean id="courseDao" class="com.feixiang.edu.dao.CourseDao">
    <property name="dataSource" ref="dataSource"/>
  </bean>

  <!-- Service 层:构造器注入(强制依赖) + Setter 注入(可选) -->
  <bean id="studentService"
        class="com.feixiang.edu.service.StudentService">
    <!-- 构造器注入:studentDao 是必须的 -->
    <constructor-arg ref="studentDao"/>
    <!-- Setter 注入:可选的最大学生数 -->
    <property name="maxEnrollment" value="50"/>
  </bean>

  <bean id="courseService"
        class="com.feixiang.edu.service.CourseService">
    <constructor-arg ref="courseDao"/>
    <constructor-arg ref="studentDao"/>
  </bean>

  <!-- 用 util 命名空间定义集合 -->
  <util:list id="adminEmails">
    <value>baige@learnto.cn</value>
    <value>daxiang@learnto.cn</value>
  </util:list>

  <bean id="notificationService"
        class="com.feixiang.edu.service.NotificationService">
    <property name="adminEmails" ref="adminEmails"/>
    <property name="systemName" value="飞翔科技教学管理系统"/>
  </bean>
</beans>

Java 代码

public class StudentService {
    private final StudentDao studentDao;       // 构造器注入(不可变)
    private int maxEnrollment = 30;             // Setter 注入(有默认值)

    public StudentService(StudentDao studentDao) {
        this.studentDao = studentDao;           // 必须依赖
    }

    public void setMaxEnrollment(int maxEnrollment) {
        this.maxEnrollment = maxEnrollment;     // 可选依赖
    }
}

操作结果

Spring 容器启动时:①创建 dataSource Bean → ②注入到 studentDao/courseDao → ③通过构造器将 studentDao 注入 studentService → ④通过 Setter 设置 maxEnrollment=50 → ⑤所有 Bean 就绪。

如果 studentDao 缺失,容器启动就会失败(构造器注入保证了依赖完整性)。

易错场景

错误一:构造器参数顺序错误

<!-- ❌ 多个同类型参数容易搞错顺序 -->
<constructor-arg ref="courseDao"/>
<constructor-arg ref="studentDao"/>

<!-- ✅ 用 index 或 name 明确指定 -->
<constructor-arg index="0" ref="courseDao"/>
<constructor-arg index="1" ref="studentDao"/>

错误二:循环依赖

<bean id="a" class="A">
  <constructor-arg ref="b"/>
</bean>
<bean id="b" class="B">
  <constructor-arg ref="a"/>
</bean>

构造器注入的循环依赖无法解决(Spring 会抛 BeanCurrentlyInCreationException)。改为 Setter 注入或重构设计。

面试考点

考点参考答案要点
Spring XML 配置中构造器注入和 Setter 注入的区别?构造器注入:强制依赖、不可变、容器启动即检测缺失;Setter 注入:可选依赖、可变、可能处于不完整状态
Spring Bean 的生命周期阶段?实例化→属性填充→BeanNameAware→BeanFactoryAware→BeanPostProcessor.before→InitializingBean→init-method→BeanPostProcessor.after→就绪→DisposableBean→destroy-method
XML 中如何注入集合类型?用 <list>/<set>/<map>/<props> 或 util 命名空间的 <util:list> 等
下一页
MyBatis XML 映射