1. 简介

在 Spring 3.0 之前,XML 是定义和配置 Bean 的唯一方式。从 Spring 3.0 开始,引入了 JavaConfig,允许我们通过 Java 类来配置 Bean。尽管如此,至今仍有不少项目在使用 XML 配置。

本文将重点讲解 如何在 Spring Boot 项目中集成 XML 配置,帮助你在现代化应用中平滑过渡或维护遗留系统。

⚠️ 虽然 JavaConfig 已成主流,但在一些老项目迁移或特定场景下,XML 依然有其价值。别一上来就否定它,有时候不是技术不行,是历史包袱太重。


2. 使用 @ImportResource 注解加载 XML 配置

@ImportResource 是 Spring 提供的用于导入外部资源(如 XML 文件)的关键注解,它可以将 XML 中定义的 Bean 注册到 Spring 容器中。

假设我们有一个 beans.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"
    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">
    
    <bean class="com.baeldung.springbootxml.Pojo">
        <property name="field" value="sample-value"></property>
    </bean>
</beans>

这个 XML 定义了一个 Pojo 类型的 Bean,并通过 setter 注入了 field 属性。

要在 Spring Boot 中启用它,只需在主配置类上添加 @ImportResource

@Configuration
@ImportResource("classpath:beans.xml")
public class SpringBootXmlApplication implements CommandLineRunner {

    @Autowired 
    private Pojo pojo;

    public static void main(String[] args) {
        SpringApplication.run(SpringBootXmlApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println(pojo.getField()); // 输出: sample-value
    }
}

✅ 运行后你会发现,pojo 成功被注入,且字段值来自 XML 配置。

💡 注意路径写法:classpath: 表示从类路径下查找,推荐使用这种写法避免路径问题。


3. 在 XML 中引用 Properties 配置

很多时候我们希望 XML 中也能使用 application.properties 里的值,比如动态配置数据库连接、开关标志等。

先在 application.properties 中定义一个属性:

sample=string loaded from properties!

然后修改 beans.xml,用占位符 ${} 引用该属性:

<bean class="com.baeldung.springbootxml.Pojo">
    <property name="field" value="${sample}"></property>
</bean>

接着写个集成测试验证是否生效:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootXmlApplication.class)
public class SpringBootXmlApplicationIntegrationTest {

    @Autowired 
    private Pojo pojo;
    
    @Value("${sample}") 
    private String sample;

    @Test
    public void whenCallingGetter_thenPrintingProperty() {
        assertThat(pojo.getField())
                .isNotBlank()
                .isEqualTo(sample);
    }
}

❌ 但运行测试会失败!原因很简单:默认情况下,Spring XML 并不自动解析 ${} 占位符

解决方案:加上 @EnableAutoConfiguration

只需要在配置类上加上 @EnableAutoConfiguration,问题就解决了:

@Configuration
@EnableAutoConfiguration
@ImportResource("classpath:beans.xml")
public class SpringBootXmlApplication implements CommandLineRunner {
    // ...
}

✅ 原理说明:

  • @EnableAutoConfiguration 不仅触发自动配置,还会注册 PropertySourcesPlaceholderConfigurer 这个关键 Bean。
  • 正是这个 Bean 负责解析 XML 和注解中的 ${} 占位符。

📌 小贴士:你也可以手动注册 PropertySourcesPlaceholderConfigurer,但不如直接用 @EnableAutoConfiguration 来得简单粗暴。


4. 推荐做法:优先使用 JavaConfig

虽然我们演示了如何在 Spring Boot 中使用 XML,但还是要说句实话:能不用就不用

以下是两个关键原因:

  • 类型安全:JavaConfig 是编译期检查的,拼错类名、方法名直接报错;XML 是运行时才发现问题。
  • 易于维护:Java 代码支持 IDE 跳转、重构、提示;XML 写多了就是“配置地狱”,尤其大项目里找一个 bean 定义堪比大海捞针。

建议迁移路径:

  1. 新功能一律用 @Configuration + @Bean
  2. 老 XML 配置逐步拆解,按模块迁移到 JavaConfig
  3. 实在不能动的,保留 XML 并用 @ImportResource 加载,但加个 TODO 注释提醒技术债

⚠️ 别在新项目里再写 XML 配置了,这不是复古潮流,是给自己挖坑。


5. 总结

本文介绍了如何在 Spring Boot 中通过 @ImportResource 导入 XML 配置文件,并解决了常见的属性占位符解析问题。

核心要点回顾:

  • ✅ 使用 @ImportResource("classpath:xxx.xml") 可加载 XML 中的 Bean
  • ❌ XML 默认不解析 ${} 占位符
  • ✅ 添加 @EnableAutoConfiguration 可自动启用属性解析
  • 🚫 长期来看,推荐迁移到 JavaConfig,更安全、更易维护

所有示例代码已托管至 GitHub:https://github.com/example/spring-boot-xml-config-demo(mock 地址)

📌 适用场景提醒:本文适用于维护老系统与旧框架集成的场景。如果是新项目,请果断选择 JavaConfig 或注解驱动模式。


原始标题:XML Defined Beans in Spring Boot