You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.x使用ContextConfiguration时如何修复TypeConverterSupport问题?

类型转换异常与Spring测试上下文配置问题

问题描述

使用以下基础YAML配置时:

myThing:
  someValue: 10

在测试中通过@ContextConfiguration启动上下文时,会触发TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:80)相关的类型转换异常,涉及字符串转Integer、Integer转String、字符串转LocalDate等操作。但改用@SpringBootTest加载完整Spring Boot上下文时,所有转换都能正常完成。推测是@ContextConfiguration中缺少实现类型转换和配置解析所需的类,但无法定位具体组件。

相关代码

MyThing组件类

package com.example.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyThing {
    @Value("${myThing.myValue}")
    private Integer myValue;

    public Integer getMyValue() {
        return myValue;
    }
}

测试类

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {MyThing.class}) // 无法正常加载上下文
class DemoApplicationTests {

    @Autowired
    private MyThing myThing;

    @Test
    void contextLoads() {
        assertEquals(10, myThing.getMyValue());
    }

}

对应YAML配置

myThing:
  myValue: 10

报错信息

Caused by: java.lang.NumberFormatException: For input string: "${myThing.myValue}"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:654)
at java.base/java.lang.Integer.valueOf(Integer.java:999)
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:203)
at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:115)
at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:439)
at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:412)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:161)
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:80)
... 39 more

解决方案

问题根源是仅加载MyThing.class的上下文过于基础,缺少Spring Boot自动配置的核心组件:一是解析${...}占位符的配置属性处理器,二是处理类型转换的服务组件。提供两种修复方式:

方式一:加载Spring Boot主配置类

直接在测试类中指定Spring Boot的主应用配置类(如DemoApplication),它会自动引入所有必要的配置组件:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {DemoApplication.class})
class DemoApplicationTests {
    // 测试代码保持不变
}

或者直接使用@SpringBootTest注解,它会默认加载完整的Spring Boot上下文:

@SpringBootTest
class DemoApplicationTests {
    // 测试代码保持不变
}

方式二:手动添加必要配置组件

如果不想加载完整Spring Boot上下文,可以手动创建测试配置类,引入占位符解析器和类型转换组件:

package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class TestConfig {
    // 配置占位符解析器,加载YAML配置文件
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setLocations(new ClassPathResource("application.yml"));
        return configurer;
    }

    // 注册LocalDate等日期类型的格式化转换器
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addFormatters(FormatterRegistry registry) {
                DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
                registrar.setUseIsoFormat(true);
                registrar.registerFormatters(registry);
            }
        };
    }
}

然后在测试类中引入该配置类:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {MyThing.class, TestConfig.class})
class DemoApplicationTests {
    // 测试代码保持不变
}

关键说明

  • PropertySourcesPlaceholderConfigurer是解析${...}占位符的核心组件,没有它,Spring会直接把占位符字符串当作字段值,导致类型转换失败。
  • Spring Boot的自动配置会默认引入这类组件,而单纯的@ContextConfiguration只会加载指定类,不会自动添加这些核心配置。
  • 对于LocalDate等日期类型,需要通过DateTimeFormatterRegistrar或自定义转换器注册格式化规则,才能完成字符串到日期的转换。

内容的提问来源于stack exchange,提问作者buddyp450

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:22:37