跳到主要内容
版本:7.0.3

使用 @Value

Hunyuan 7b 中英对照 Using @Value Using @Value

@Value 通常用于注入外部化的属性:

@Component
public class MovieRecommender {

private final String catalog;

public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}

使用以下配置:

@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }

以及以下的 application.properties 文件:

catalog.name=MovieCatalog

在这种情况下,catalog 参数和字段将等于 MovieCatalog 的值。

Spring提供了一个默认的宽松嵌入式值解析器。它会尝试解析属性值,如果无法解析,则会将属性名(例如 ${catalog.name})作为值进行注入。如果您希望对不存在的值进行严格控制,应该声明一个 PropertySourcesPlaceholderConfigurer bean,如下例所示:

@Configuration
public class AppConfig {

@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
备注

在使用JavaConfig配置PropertySourcesPlaceholderConfigurer时,@Bean方法必须是static的。

使用上述配置可以确保,如果任何 ${} 占位符无法解析,则 Spring 初始化会失败。还可以使用 setPlaceholderPrefix(), setPlaceholderSuffix(), setValueSeparator(), 或 setEscapeCharacter() 等方法来自定义占位符的语法。此外,可以通过设置 JVM 系统属性(或通过 SpringProperties 机制)来全局更改或禁用默认的转义字符,即 spring.placeholder.escapeCharacter.default 属性。

备注

Spring Boot 默认配置了一个 PropertySourcesPlaceholderConfigurer bean,该 bean 会从 application.propertiesapplication.yml 文件中获取属性。

Spring 提供的内置转换器支持可以自动处理简单的类型转换(例如转换为 Integerint)。多个用逗号分隔的值可以自动转换为 String 数组,而无需额外操作。

可以按照以下方式提供一个默认值:

@Component
public class MovieRecommender {

private final String catalog;

public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
this.catalog = catalog;
}
}

Spring的BeanPostProcessor在后台使用ConversionService来处理将@Value中的String值转换为目标类型的过程。如果你想为自定义类型提供转换支持,可以像下面的例子所示,提供一个自己的ConversionService bean实例:

@Configuration
public class AppConfig {

@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}

@Value包含SpEL表达式时,该值将在运行时动态计算,如下例所示:

@Component
public class MovieRecommender {

private final String catalog;

public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) {
this.catalog = catalog;
}
}

SpEL还支持使用更复杂的数据结构:

@Component
public class MovieRecommender {

private final Map<String, Integer> countOfMoviesPerCatalog;

public MovieRecommender(
@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
}
}