從 1.3 開始,Micronaut 支持不可變配置的定義。
有兩種方法可以定義不可變配置。首選方法是定義一個用@ConfigurationProperties 注釋的接口。例如:
@ConfigurationProperties 示例
Java |
Groovy |
Kotlin |
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.core.bind.annotation.Bindable;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Optional;
@ConfigurationProperties("my.engine") // (1)
public interface EngineConfig {
@Bindable(defaultValue = "Ford") // (2)
@NotBlank // (3)
String getManufacturer();
@Min(1L)
int getCylinders();
@NotNull
CrankShaft getCrankShaft(); // (4)
@ConfigurationProperties("crank-shaft")
interface CrankShaft { // (5)
Optional<Double> getRodLength(); // (6)
}
}
|
import io.micronaut.context.annotation.ConfigurationProperties
import io.micronaut.core.bind.annotation.Bindable
import javax.validation.constraints.Min
import javax.validation.constraints.NotBlank
import javax.validation.constraints.NotNull
@ConfigurationProperties("my.engine") // (1)
interface EngineConfig {
@Bindable(defaultValue = "Ford") // (2)
@NotBlank // (3)
String getManufacturer()
@Min(1L)
int getCylinders()
@NotNull
CrankShaft getCrankShaft() // (4)
@ConfigurationProperties("crank-shaft")
static interface CrankShaft { // (5)
Optional<Double> getRodLength() // (6)
}
}
|
import io.micronaut.context.annotation.ConfigurationProperties
import io.micronaut.core.bind.annotation.Bindable
import javax.validation.constraints.Min
import javax.validation.constraints.NotBlank
import javax.validation.constraints.NotNull
@ConfigurationProperties("my.engine") // (1)
interface EngineConfig {
@get:Bindable(defaultValue = "Ford") // (2)
@get:NotBlank // (3)
val manufacturer: String
@get:Min(1L)
val cylinders: Int
@get:NotNull
val crankShaft: CrankShaft // (4)
@ConfigurationProperties("crank-shaft")
interface CrankShaft { // (5)
val rodLength: Double? // (6)
}
}
|
@ConfigurationProperties 注釋采用配置前綴并在接口上聲明
您可以使用@Bindable 設置默認值
也可以使用驗證注解
您還可以指定對其他 @ConfigurationProperties beans 的引用。
您可以嵌套不可變配置
可以通過返回 Optional 或指定 @Nullable 來指示可選配置
在這種情況下,Micronaut 提供了一個編譯時實現(xiàn),它委托所有 getter 調用 Environment 接口的 getProperty(..) 方法。
這樣做的好處是,如果應用程序配置被刷新(例如通過調用 /refresh 端點),注入的接口會自動看到新值。
如果您嘗試指定除 getter 之外的任何其他抽象方法,則會發(fā)生編譯錯誤(支持默認方法)。
另一種實現(xiàn)不可變配置的方法是定義一個類并在 @ConfigurationProperties 或 @EachProperty bean 的構造函數(shù)上使用 @ConfigurationInject 注釋。
例如:
@ConfigurationProperties 示例
Java |
Groovy |
Kotlin |
import io.micronaut.core.bind.annotation.Bindable;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.context.annotation.ConfigurationInject;
import io.micronaut.context.annotation.ConfigurationProperties;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Optional;
@ConfigurationProperties("my.engine") // (1)
public class EngineConfig {
private final String manufacturer;
private final int cylinders;
private final CrankShaft crankShaft;
@ConfigurationInject // (2)
public EngineConfig(
@Bindable(defaultValue = "Ford") @NotBlank String manufacturer, // (3)
@Min(1L) int cylinders, // (4)
@NotNull CrankShaft crankShaft) {
this.manufacturer = manufacturer;
this.cylinders = cylinders;
this.crankShaft = crankShaft;
}
public String getManufacturer() {
return manufacturer;
}
public int getCylinders() {
return cylinders;
}
public CrankShaft getCrankShaft() {
return crankShaft;
}
@ConfigurationProperties("crank-shaft")
public static class CrankShaft { // (5)
private final Double rodLength; // (6)
@ConfigurationInject
public CrankShaft(@Nullable Double rodLength) {
this.rodLength = rodLength;
}
public Optional<Double> getRodLength() {
return Optional.ofNullable(rodLength);
}
}
}
|
import io.micronaut.context.annotation.ConfigurationInject
import io.micronaut.context.annotation.ConfigurationProperties
import io.micronaut.core.bind.annotation.Bindable
import javax.annotation.Nullable
import javax.validation.constraints.Min
import javax.validation.constraints.NotBlank
import javax.validation.constraints.NotNull
@ConfigurationProperties("my.engine") // (1)
class EngineConfig {
final String manufacturer
final int cylinders
final CrankShaft crankShaft
@ConfigurationInject // (2)
EngineConfig(
@Bindable(defaultValue = "Ford") @NotBlank String manufacturer, // (3)
@Min(1L) int cylinders, // (4)
@NotNull CrankShaft crankShaft) {
this.manufacturer = manufacturer
this.cylinders = cylinders
this.crankShaft = crankShaft
}
@ConfigurationProperties("crank-shaft")
static class CrankShaft { // (5)
private final Double rodLength // (6)
@ConfigurationInject
CrankShaft(@Nullable Double rodLength) {
this.rodLength = rodLength
}
Optional<Double> getRodLength() {
Optional.ofNullable(rodLength)
}
}
}
|
import io.micronaut.context.annotation.ConfigurationInject
import io.micronaut.context.annotation.ConfigurationProperties
import io.micronaut.core.bind.annotation.Bindable
import java.util.Optional
import javax.validation.constraints.Min
import javax.validation.constraints.NotBlank
import javax.validation.constraints.NotNull
@ConfigurationProperties("my.engine") // (1)
data class EngineConfig @ConfigurationInject // (2)
constructor(
@Bindable(defaultValue = "Ford") @NotBlank val manufacturer: String, // (3)
@Min(1) val cylinders: Int, // (4)
@NotNull val crankShaft: CrankShaft) {
@ConfigurationProperties("crank-shaft")
data class CrankShaft @ConfigurationInject
constructor(// (5)
private val rodLength: Double? // (6)
) {
fun getRodLength(): Optional<Double> {
return Optional.ofNullable(rodLength)
}
}
}
|
@ConfigurationProperties 注解采用配置前綴
@ConfigurationInject 注釋在構造函數(shù)上定義
您可以使用@Bindable 設置默認值
也可以使用驗證注解
您可以嵌套不可變配置
可選配置可以用 @Nullable 表示
@ConfigurationInject 注釋向 Micronaut 提供了一個提示,以優(yōu)先考慮來自配置的綁定值而不是注入 bean。
使用這種方法,要使配置可刷新,還要將 @Refreshable 注釋添加到類中。這允許在運行時配置刷新事件的情況下重新創(chuàng)建 bean。
這條規(guī)則有一些例外。如果滿足以下任何條件,Micronaut 將不會對參數(shù)執(zhí)行配置綁定:
參數(shù)用@Value注解(顯式綁定)
參數(shù)用@Property注解(顯式綁定)
參數(shù)用@Parameter注解(參數(shù)化bean處理)
參數(shù)用@Inject注解(generic bean injection)
參數(shù)的類型用bean作用域注解(比如@Singleton)
一旦你準備好了一個類型安全的配置,它就可以像任何其他 bean 一樣注入到你的 bean 中:
@ConfigurationProperties 依賴注入
Java |
Groovy |
Kotlin |
@Singleton
public class Engine {
private final EngineConfig config;
public Engine(EngineConfig config) {// (1)
this.config = config;
}
public int getCylinders() {
return config.getCylinders();
}
public String start() {// (2)
return getConfig().getManufacturer() + " Engine Starting V" + getConfig().getCylinders() +
" [rodLength=" + getConfig().getCrankShaft().getRodLength().orElse(6.0d) + "]";
}
public final EngineConfig getConfig() {
return config;
}
}
|
@Singleton
class Engine {
private final EngineConfig config
Engine(EngineConfig config) {// (1)
this.config = config
}
int getCylinders() {
return config.cylinders
}
String start() {// (2)
return "$config.manufacturer Engine Starting V$config.cylinders [rodLength=${config.crankShaft.rodLength.orElse(6.0d)}]"
}
final EngineConfig getConfig() {
return config
}
}
|
@Singleton
class Engine(val config: EngineConfig)// (1)
{
val cylinders: Int
get() = config.cylinders
fun start(): String {// (2)
return "${config.manufacturer} Engine Starting V${config.cylinders} [rodLength=${config.crankShaft.getRodLength().orElse(6.0)}]"
}
}
|
注入 EngineConfig bean
使用配置屬性
然后可以在運行應用程序時提供配置值。例如:
供應配置
Java |
Groovy |
Kotlin |
ApplicationContext applicationContext = ApplicationContext.run(CollectionUtils.mapOf(
"my.engine.cylinders", "8",
"my.engine.crank-shaft.rod-length", "7.0"
));
Vehicle vehicle = applicationContext.getBean(Vehicle.class);
System.out.println(vehicle.start());
|
ApplicationContext applicationContext = ApplicationContext.run(
"my.engine.cylinders": "8",
"my.engine.crank-shaft.rod-length": "7.0"
)
Vehicle vehicle = applicationContext.getBean(Vehicle)
System.out.println(vehicle.start())
|
val map = mapOf(
"my.engine.cylinders" to "8",
"my.engine.crank-shaft.rod-length" to "7.0"
)
val applicationContext = ApplicationContext.run(map)
val vehicle = applicationContext.getBean(Vehicle::class.java)
println(vehicle.start())
|
上面的示例打印:“Ford Engine Starting V8 [rodLength=7B.0]”
自定義訪問器
正如更改訪問器樣式中已經解釋的那樣,也可以在創(chuàng)建不可變配置屬性時自定義訪問器:
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.core.annotation.AccessorsStyle;
import io.micronaut.core.bind.annotation.Bindable;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Optional;
@ConfigurationProperties("my.engine") (1)
@AccessorsStyle(readPrefixes = "read") (2)
public interface EngineConfigAccessors {
@Bindable(defaultValue = "Ford")
@NotBlank
String readManufacturer(); (3)
@Min(1L)
int readCylinders(); (3)
@NotNull
CrankShaft readCrankShaft(); (3)
@ConfigurationProperties("crank-shaft")
@AccessorsStyle(readPrefixes = "read") (4)
interface CrankShaft {
Optional<Double> readRodLength(); (5)
}
}
@ConfigurationProperties 注釋采用配置前綴并在接口上聲明
@AccessorsStyle 注解將 readPrefixes 定義為已讀。
getter 都以 read 為前綴。
嵌套的不可變配置也可以使用 @ConfigurationProperties 進行注解。
getter 以 read 為前綴。
更多建議: