根据@qualifier名称生成spring bean

时间:2019-06-28 05:03:25

标签: java spring

是否可以基于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一起工作,该工厂在限定符中看到值/名称

@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,因此我什至没有可见的构造器)

4 个答案:

答案 0 :(得分:0)

您需要使用以下限定词创建类: @Component(“ clsA”) 公共类classA

传递'clsA'并带有限定符名称

答案 1 :(得分:0)

您需要给您的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。     @返回建议的组件名称(如果有)(或空字符串)   否则)

答案 2 :(得分:0)

我认为您需要的是一个配置类。

@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;
}

答案 3 :(得分:0)

并非完全符合您的要求,但我看不出这是不是等效的。

提供工厂bean

@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(); }
}