您可以使用 @Value 注释将配置值注入到 bean 中。
使用@Value 注解
考虑以下示例:
@Value Example
Java |
Groovy |
Kotlin |
import io.micronaut.context.annotation.Value;
import jakarta.inject.Singleton;
@Singleton
public class EngineImpl implements Engine {
@Value("${my.engine.cylinders:6}") // (1)
protected int cylinders;
@Override
public int getCylinders() {
return cylinders;
}
@Override
public String start() {// (2)
return "Starting V" + getCylinders() + " Engine";
}
}
|
import io.micronaut.context.annotation.Value
import jakarta.inject.Singleton
@Singleton
class EngineImpl implements Engine {
@Value('${my.engine.cylinders:6}') // (1)
protected int cylinders
@Override
int getCylinders() {
cylinders
}
@Override
String start() { // (2)
"Starting V$cylinders Engine"
}
}
|
import io.micronaut.context.annotation.Value
import jakarta.inject.Singleton
@Singleton
class EngineImpl : Engine {
@Value("\${my.engine.cylinders:6}") // (1)
override var cylinders: Int = 0
protected set
override fun start(): String { // (2)
return "Starting V$cylinders Engine"
}
}
|
@Value 注解接受一个可以嵌入占位符值的字符串(默认值可以通过在冒号 : 字符后指定一个值来提供)。还要尽量避免将成员可见性设置为私有,因为这需要 Micronaut 框架使用反射。更喜欢使用受保护的。
然后可以在代码中使用注入的值。
请注意,@Value 也可用于注入静态值。例如,以下注入数字 10:
Static @Value Example
@Value("10")
int number;
当用于组合静态内容和占位符的注入值时,这会更有用。例如设置一个 URL:
Placeholders with @Value
@Value("http://${my.host}:${my.port}")
URL url;
在上面的示例中,URL 由配置中必须存在的两个占位符属性构成:my.host 和 my.port。
请记住,要在占位符表达式中指定默认值,请使用冒号 : 字符。但是,如果您指定的默认值包含冒号,则必须使用反引号对值进行转义。例如:
Placeholders with @Value
@Value("${my.url:`http://foo.com`}")
URL url;
请注意,@Value 本身在属性值占位符的解析方面没有什么特别之处。
由于 Micronaut 对注释元数据的广泛支持,您可以在任何注释上使用属性占位符表达式。例如,要使 @Controller 的路径可配置,您可以执行以下操作:
@Controller("${hello.controller.path:/hello}")
class HelloController {
...
}
在上面的例子中,如果在配置中指定了 hello.controller.path,控制器将被映射到指定的路径,否则它将被映射到 /hello。
您还可以使 @Client 的目标服务器可配置(尽管服务发现方法通常更好),例如:
@Client("${my.server.url:`http://localhost:8080`}")
interface HelloClient {
...
}
在上面的示例中,属性 my.server.url 可用于配置客户端,否则客户端会回退到本地主机地址。
使用@Property 注解
回想一下,@Value 注释接收一个 String 值,它可以是静态内容和占位符表达式的混合。如果您尝试执行以下操作,这可能会导致混淆:
Incorrect usage of @Value
@Value("my.url")
String url;
在上述情况下,文字字符串值 my.url 被注入并设置为 url 字段,而不是应用程序配置中 my.url 属性的值。这是因为@Value 仅解析指定给它的值内的占位符。
要注入特定的属性名称,您最好使用 @Property:
Using @Property
Java |
Groovy |
Kotlin |
import io.micronaut.context.annotation.Property;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
@Singleton
public class Engine {
@Property(name = "my.engine.cylinders") // (1)
protected int cylinders; // (2)
private String manufacturer;
public int getCylinders() {
return cylinders;
}
public String getManufacturer() {
return manufacturer;
}
@Inject
public void setManufacturer(@Property(name = "my.engine.manufacturer") String manufacturer) { // (3)
this.manufacturer = manufacturer;
}
}
|
import io.micronaut.context.annotation.Property
import jakarta.inject.Singleton
@Singleton
class Engine {
@Property(name = "my.engine.cylinders") // (1)
protected int cylinders // (2)
@Property(name = "my.engine.manufacturer") //(3)
String manufacturer
int getCylinders() {
cylinders
}
}
|
import io.micronaut.context.annotation.Property
import jakarta.inject.Inject
import jakarta.inject.Singleton
@Singleton
class Engine {
@field:Property(name = "my.engine.cylinders") // (1)
protected var cylinders: Int = 0 // (2)
@set:Inject
@setparam:Property(name = "my.engine.manufacturer") // (3)
var manufacturer: String? = null
fun cylinders(): Int {
return cylinders
}
}
|
my.engine.cylinders 属性从配置中解析并注入到字段中。
受注入的字段不应该是私有的,因为必须使用昂贵的反射
@Property注解用于通过setter注入
因为无法使用@Property 定义默认值,如果该值不存在或无法转换为所需的类型,bean 实例化将失败。
以上改为注入从应用程序配置解析的 my.url 属性的值。如果在配置中找不到该属性,则会抛出异常。与其他类型的注入一样,注入点也可以用@Nullable注解,使注入成为可选的。
您还可以使用此功能来解析子映射。例如,考虑以下配置:
Properties |
Yaml |
Toml |
Groovy |
Hocon |
JSON |
datasources.default.name=mydb
jpa.default.properties.hibernate.hbm2ddl.auto=update
jpa.default.properties.hibernate.show_sql=true
|
datasources:
default:
name: 'mydb'
jpa:
default:
properties:
hibernate:
hbm2ddl:
auto: update
show_sql: true
|
[datasources]
[datasources.default]
name="mydb"
[jpa]
[jpa.default]
[jpa.default.properties]
[jpa.default.properties.hibernate]
[jpa.default.properties.hibernate.hbm2ddl]
auto="update"
show_sql=true
|
datasources {
'default' {
name = "mydb"
}
}
jpa {
'default' {
properties {
hibernate {
hbm2ddl {
auto = "update"
}
show_sql = true
}
}
}
}
|
{
datasources {
default {
name = "mydb"
}
}
jpa {
default {
properties {
hibernate {
hbm2ddl {
auto = "update"
}
show_sql = true
}
}
}
}
}
|
{
"datasources": {
"default": {
"name": "mydb"
}
},
"jpa": {
"default": {
"properties": {
"hibernate": {
"hbm2ddl": {
"auto": "update"
},
"show_sql": true
}
}
}
}
}
|
要解析仅包含以 hibernate 开头的属性的扁平化映射,请使用 @Property,例如:
Using @Property
@Property(name = "jpa.default.properties")
Map<String, String> jpaProperties;
注入的映射将包含键 hibernate.hbm2ddl.auto 和 hibernate.show_sql 及其值。
@MapFormat 注释可用于根据您想要嵌套键还是平面键来自定义注入的映射,并且它允许通过 StringConvention 枚举自定义键样式。
更多建议: