@ConfigurationProperties 注釋非常適合單個配置類,但有時您需要多個實(shí)例,每個實(shí)例都有自己獨(dú)特的配置。這就是 EachProperty 的用武之地。
@EachProperty 注釋為給定名稱中的每個子屬性創(chuàng)建一個 ConfigurationProperties bean。作為示例,請考慮以下類:
使用@EachProperty
Java |
Groovy |
Kotlin |
import java.net.URI;
import java.net.URISyntaxException;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.EachProperty;
@EachProperty("test.datasource") // (1)
public class DataSourceConfiguration {
private final String name;
private URI url = new URI("localhost");
public DataSourceConfiguration(@Parameter String name) // (2)
throws URISyntaxException {
this.name = name;
}
public String getName() {
return name;
}
public URI getUrl() { // (3)
return url;
}
public void setUrl(URI url) {
this.url = url;
}
}
|
import io.micronaut.context.annotation.EachProperty
import io.micronaut.context.annotation.Parameter
@EachProperty("test.datasource") // (1)
class DataSourceConfiguration {
final String name
URI url = new URI("localhost") // (3)
DataSourceConfiguration(@Parameter String name) // (2)
throws URISyntaxException {
this.name = name
}
}
|
import io.micronaut.context.annotation.EachProperty
import io.micronaut.context.annotation.Parameter
import java.net.URI
import java.net.URISyntaxException
@EachProperty("test.datasource") // (1)
class DataSourceConfiguration
@Throws(URISyntaxException::class)
constructor(@param:Parameter val name: String) { // (2)
var url = URI("localhost") // (3)
}
|
@EachProperty 注解定義了要處理的屬性名。
@Parameter注解可用于注入定義bean名稱的子屬性名稱(也是bean限定符)
bean 的每個屬性都綁定到配置。
上面的 DataSourceConfiguration 定義了一個 url 屬性來配置一個或多個數(shù)據(jù)源??梢允褂脤?nbsp;Micronaut 評估的任何 PropertySource 實(shí)例配置 URL 本身:
向@EachProperty 提供配置
Java |
Groovy |
Kotlin |
ApplicationContext applicationContext = ApplicationContext.run(PropertySource.of(
"test",
CollectionUtils.mapOf(
"test.datasource.one.url", "jdbc:mysql://localhost/one",
"test.datasource.two.url", "jdbc:mysql://localhost/two")
));
|
ApplicationContext applicationContext = ApplicationContext.run(PropertySource.of(
"test",
[
"test.datasource.one.url": "jdbc:mysql://localhost/one",
"test.datasource.two.url": "jdbc:mysql://localhost/two"
]
))
|
val applicationContext = ApplicationContext.run(PropertySource.of(
"test",
mapOf(
"test.datasource.one.url" to "jdbc:mysql://localhost/one",
"test.datasource.two.url" to "jdbc:mysql://localhost/two"
)
))
|
在上面的示例中,兩個數(shù)據(jù)源(稱為一和二)在前面定義的 @EachProperty 注釋中的 test.datasource 前綴下定義。這些配置條目中的每一個都會觸發(fā)新的 DataSourceConfiguration bean 的創(chuàng)建,以便以下測試成功:
評估由@EachProperty 構(gòu)建的 Bean
Java |
Groovy |
Kotlin |
Collection<DataSourceConfiguration> beansOfType = applicationContext.getBeansOfType(DataSourceConfiguration.class);
assertEquals(2, beansOfType.size()); // (1)
DataSourceConfiguration firstConfig = applicationContext.getBean(
DataSourceConfiguration.class,
Qualifiers.byName("one") // (2)
);
assertEquals(
new URI("jdbc:mysql://localhost/one"),
firstConfig.getUrl()
);
|
when:
Collection<DataSourceConfiguration> beansOfType = applicationContext.getBeansOfType(DataSourceConfiguration.class)
assertEquals(2, beansOfType.size()) // (1)
DataSourceConfiguration firstConfig = applicationContext.getBean(
DataSourceConfiguration.class,
Qualifiers.byName("one") // (2)
)
then:
new URI("jdbc:mysql://localhost/one") == firstConfig.getUrl()
|
val beansOfType = applicationContext.getBeansOfType(DataSourceConfiguration::class.java)
assertEquals(2, beansOfType.size) // (1)
val firstConfig = applicationContext.getBean(
DataSourceConfiguration::class.java,
Qualifiers.byName("one") // (2)
)
assertEquals(
URI("jdbc:mysql://localhost/one"),
firstConfig.url
)
|
可以使用 getBeansOfType 檢索所有 DataSourceConfiguration 類型的 beans
可以使用 byName 限定符檢索單個 bean。
基于列表的綁定
@EachProperty 的默認(rèn)行為是從映射樣式的配置進(jìn)行綁定,其中鍵是 bean 的命名限定符,值是要綁定的數(shù)據(jù)。對于地圖樣式配置沒有意義的情況,可以通知 Micronaut 該類是從列表中綁定的。只需將注釋上的列表成員設(shè)置為 true。
@EachProperty 列表示例
Java |
Groovy |
Kotlin |
import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.core.order.Ordered;
import java.time.Duration;
@EachProperty(value = "ratelimits", list = true) // (1)
public class RateLimitsConfiguration implements Ordered { // (2)
private final Integer index;
private Duration period;
private Integer limit;
RateLimitsConfiguration(@Parameter Integer index) { // (3)
this.index = index;
}
@Override
public int getOrder() {
return index;
}
public Duration getPeriod() {
return period;
}
public void setPeriod(Duration period) {
this.period = period;
}
public Integer getLimit() {
return limit;
}
public void setLimit(Integer limit) {
this.limit = limit;
}
}
|
import io.micronaut.context.annotation.EachProperty
import io.micronaut.context.annotation.Parameter
import io.micronaut.core.order.Ordered
import java.time.Duration
@EachProperty(value = "ratelimits", list = true) // (1)
class RateLimitsConfiguration implements Ordered { // (2)
private final Integer index
Duration period
Integer limit
RateLimitsConfiguration(@Parameter Integer index) { // (3)
this.index = index
}
@Override
int getOrder() {
index
}
}
|
import io.micronaut.context.annotation.EachProperty
import io.micronaut.context.annotation.Parameter
import io.micronaut.core.order.Ordered
import java.time.Duration
@EachProperty(value = "ratelimits", list = true) // (1)
class RateLimitsConfiguration
constructor(@param:Parameter private val index: Int) // (3)
: Ordered { // (2)
var period: Duration? = null
var limit: Int? = null
override fun getOrder(): Int {
return index
}
}
|
注解的列表成員設(shè)置為true
如果在檢索 bean 時順序很重要,則實(shí)施 Ordered
索引被注入到構(gòu)造函數(shù)中
更多建議: