使用 @Value
@Value 通常用于注入外部化属性:
-
Java
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
具有以下配置:
-
Java
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {
}
以及以下 application.properties 文件:
catalog.name=MovieCatalog
在这种情况下,catalog 参数和字段将等于 MovieCatalog 值。
Infra 提供了默认的宽松嵌入式值解析器。它将尝试解析属性值,如果无法解析,属性名称(例如 ${catalog.name})将作为值注入。
如果您想对不存在的值保持严格控制,您应该声明一个 PropertySourcesPlaceholderConfigurer bean,如下例所示:
-
Java
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
使用 JavaConfig 配置 PropertySourcesPlaceholderConfigurer 时,@Bean 方法必须是 static。
|
使用上述配置可确保如果任何 ${} 占位符无法解析,Infra 初始化将失败。
也可以使用 setPlaceholderPrefix、setPlaceholderSuffix、setValueSeparator 或 setEscapeCharacter 等方法来自定义占位符。
Infra App 默认配置一个 PropertySourcesPlaceholderConfigurer bean,该 bean 将从 application.properties 和 application.yml 文件中获取属性。
|
Infra 提供的内置转换器支持允许自动处理简单的类型转换(例如转换为 Integer 或 int)。
多个逗号分隔的值可以自动转换为 String 数组,而无需额外的努力。
可以提供默认值,如下所示:
-
Java
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
this.catalog = catalog;
}
}
Infra BeanPostProcessor 在幕后使用 ConversionService 来处理将 @Value 中的 String 值转换为目标类型的过程。
如果您想为自己的自定义类型提供转换支持,您可以提供自己的 ConversionService bean 实例,如下例所示:
-
Java
@Configuration
public class AppConfig {
@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}
当 @Value 包含 SpEL 表达式 时,该值将在运行时动态计算,如下例所示:
-
Java
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) {
this.catalog = catalog;
}
}
SpEL 还支持使用更复杂的数据结构:
-
Java
@Component
public class MovieRecommender {
private final Map<String, Integer> countOfMoviesPerCatalog;
public MovieRecommender(@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
}
}