簡體   English   中英

根據@qualifier名稱生成spring bean

[英]Generate spring beans based on @qualifier names

是否可以基於Qualifier中的值創建bean? 我希望能夠僅使用包含度量標准名稱的限定符來標記千分尺/量規/等。

@Autowired
@Qualifer("my.service.my.metric") Counter metric;

春天會給我:

metricRegister.counter("my.service.my.metric")

我的Google Fu令我失望,而且我看不到一種明顯的方式來做我想做的事。

編輯更多上下文:我只是想擺脫構造函數中發生的邏輯,並避免為每個指標配置Config樣板

當前方式:

@Service
class MyService {

  private Counter counter1;
  private Counter counter2;

  MyService(MeterRegistry registry) {
     this.counter1 = registry.counter("someMetric");
     this.counter2 = registry.counter("otherMetric");
  }
}

我想與某種專用BeanFactory一起工作的東西,它可以在Qualifier中看到值/名稱

@Service
class MyService {
  private Counter counter1;
  private Counter counter2;

  MyService(@Qualifer("someMetric") Counter counter1, @Qualifier("otherMetric") Counter counter2) {
    this.counter1 = counter1;
    this.counter2 = counter2;
  }
}

(實際上,我將在生成器生成器中使用lombok,因此我什至沒有可見的構造器)

您需要使用如下限定詞來創建您的類:@Component(“ clsA”)public class classA

並通過“ clsA”具有限定詞名稱

您需要給Bean/Component一個名字:

import org.springframework.stereotype.Component;

@Component("my.service.my.metric")
public class Counter {
    // Code
}

之后,您將可以使用:

@Autowired
@Qualifer("my.service.my.metric") 
Counter metric;

如Spring文檔中所述,關於您傳遞給@Component

該值可能表明建議使用邏輯組件名稱,以在自動檢測到組件的情況下將其轉換為Spring bean。 @返回建議的組件名稱(如果有)(否則返回空字符串)

我認為您需要的是配置類。

@Configuration
class MetricConfiguration {
    public static final String METRIC_1_NAME = "your.metric.name";
    public static final String METRIC_2_NAME = "your.other.metric.name";

    @Bean(METRIC_1_NAME)
    public Counter(MetricsRegistry registry) {
        return registry.counter(METRIC_1_NAME, counter);
    }

    @Bean(METRIC_2_NAME)
    public Counter(MetricsRegistry registry) {
        return registry.counter(METRIC_2_NAME, counter);
    }
}

然后您可以通過注入

@Service
class YourService {
    @Autowired
    @Qualifier(MetricConfiguration.METRIC_1_NAME)
    Counter metric1Counter;
}

@Service
class YourOtherService {
    @Autowired
    @Qualifier(MetricConfiguration.METRIC_2_NAME)
    Counter metric2Counter;
}

並非完全是您要的,但我看不出這有什么不同。

提供工廠豆

@Service public class CounterFactory {
    @Autowired private MeterRegistry registry;

    // cache already created counters; you could also use Spring's caching
    Map<String, Counter> createdCounters = new HashMap<>();

    public Counter createCounter(String metricName) {
        return createdCounters.computeIfAbsent(metricName, s -> registry.counter(s));
    }
}

現在,你不能 Counter用豆

@Service public class CounterClient {
    private static final String METRIC_NAME = "my_metric_name";
    @Autowired @Qualifier(METRIC_NAME)
    private Counter metric;

    public void triggerMetric() { metric.inc(); }
}

但是我覺得這樣也一樣。

@Service public class CounterClient {
    private static final String METRIC_NAME = "my_metric_name";
    private Counter metric;

    CounterClient(CounterFactory factory) {
        metric = factory.createCounter(METRIC_NAME);
    }

    public void triggerMetric() { metric.inc(); }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM