首页
/
Micronaut 中文教程
/
Micronaut 不可变配置
Micronaut 不可变配置
从 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 提供了一个编译时实现,它委托所有 getter 调用 Environment 接口的 getProperty(..) 方法。
这样做的好处是,如果应用程序配置被刷新(例如通过调用 /refresh 端点),注入的接口会自动看到新值。
如果您尝试指定除 getter 之外的任何其他抽象方法,则会发生编译错误(支持默认方法)。
另一种实现不可变配置的方法是定义一个类并在 @ConfigurationProperties 或 @EachProperty bean 的构造函数上使用 @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 注释在构造函数上定义
您可以使用@Bindable 设置默认值
也可以使用验证注解
您可以嵌套不可变配置
可选配置可以用 @Nullable 表示
@ConfigurationInject 注释向 Micronaut 提供了一个提示,以优先考虑来自配置的绑定值而不是注入 bean。
使用这种方法,要使配置可刷新,还要将 @Refreshable 注释添加到类中。这允许在运行时配置刷新事件的情况下重新创建 bean。
这条规则有一些例外。如果满足以下任何条件,Micronaut 将不会对参数执行配置绑定:
参数用@Value注解(显式绑定)
参数用@Property注解(显式绑定)
参数用@Parameter注解(参数化bean处理)
参数用@Inject注解(generic bean injection)
参数的类型用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]”
自定义访问器
正如更改访问器样式中已经解释的那样,也可以在创建不可变配置属性时自定义访问器:
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 为前缀。