Micronaut 使用@EachProperty 驅(qū)動配置

2023-03-01 16:16 更新

@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)
}
  1. @EachProperty 注解定義了要處理的屬性名。

  2. @Parameter注解可用于注入定義bean名稱的子屬性名稱(也是bean限定符)

  3. 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
)
  1. 可以使用 getBeansOfType 檢索所有 DataSourceConfiguration 類型的 beans

  2. 可以使用 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
    }
}
  1. 注解的列表成員設(shè)置為true

  2. 如果在檢索 bean 時順序很重要,則實(shí)施 Ordered

  3. 索引被注入到構(gòu)造函數(shù)中


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號