使用 @Value
@Value 通常用於注入外部化屬性
-
Java
-
Kotlin
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
@Component
class MovieRecommender(@Value("\${catalog.name}") private val catalog: String)
透過以下配置
-
Java
-
Kotlin
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig { }
@Configuration
@PropertySource("classpath:application.properties")
class AppConfig
以及以下 application.properties 檔案
catalog.name=MovieCatalog
在這種情況下,catalog 引數和欄位將等於 MovieCatalog 值。
Spring 提供了一個預設的寬鬆嵌入式值解析器。它將嘗試解析屬性值,如果無法解析,屬性名(例如 ${catalog.name})將作為值注入。如果你想嚴格控制不存在的值,你應該宣告一個 PropertySourcesPlaceholderConfigurer bean,如下例所示
-
Java
-
Kotlin
@Configuration
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
@Configuration
class AppConfig {
@Bean
fun propertyPlaceholderConfigurer() = PropertySourcesPlaceholderConfigurer()
}
使用 JavaConfig 配置 PropertySourcesPlaceholderConfigurer 時,@Bean 方法必須是 static。 |
使用上述配置可確保如果任何 ${} 佔位符無法解析,Spring 初始化將失敗。還可以使用 setPlaceholderPrefix()、setPlaceholderSuffix()、setValueSeparator() 或 setEscapeCharacter() 等方法來自定義佔位符語法。此外,可以透過 JVM 系統屬性(或透過 SpringProperties 機制)設定 spring.placeholder.escapeCharacter.default 屬性來全域性更改或停用預設跳脫字元。
Spring Boot 預設配置了一個 PropertySourcesPlaceholderConfigurer bean,它將從 application.properties 和 application.yml 檔案中獲取屬性。 |
Spring 提供的內建轉換器支援允許自動處理簡單的型別轉換(例如轉換為 Integer 或 int)。多個逗號分隔的值可以自動轉換為 String 陣列,無需額外工作。
可以如下提供一個預設值
-
Java
-
Kotlin
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
this.catalog = catalog;
}
}
@Component
class MovieRecommender(@Value("\${catalog.name:defaultCatalog}") private val catalog: String)
Spring BeanPostProcessor 在幕後使用 ConversionService 來處理將 @Value 中的 String 值轉換為目標型別的過程。如果你想為自己的自定義型別提供轉換支援,你可以提供自己的 ConversionService bean 例項,如下例所示
-
Java
-
Kotlin
@Configuration
public class AppConfig {
@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}
@Configuration
class AppConfig {
@Bean
fun conversionService(): ConversionService {
return DefaultFormattingConversionService().apply {
addConverter(MyCustomConverter())
}
}
}
當 @Value 包含 SpEL 表示式 時,該值將在執行時動態計算,如下例所示
-
Java
-
Kotlin
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog) {
this.catalog = catalog;
}
}
@Component
class MovieRecommender(
@Value("#{systemProperties['user.catalog'] + 'Catalog' }") private val catalog: String)
SpEL 還支援使用更復雜的資料結構
-
Java
-
Kotlin
@Component
public class MovieRecommender {
private final Map<String, Integer> countOfMoviesPerCatalog;
public MovieRecommender(
@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
}
}
@Component
class MovieRecommender(
@Value("#{{'Thriller': 100, 'Comedy': 300}}") private val countOfMoviesPerCatalog: Map<String, Int>)