首页 > 解决方案 > 使用 @ConfigurationProperties 处理多个相同的属性

问题描述

我有Properties几个不同的豆类。值来自application.yaml

@Configuration
@Getter
@Setter
public class RabbitProperties {

    private String requestExchangeName;
    private String requestQueueName;
    private String responseExchangeName;
    private String deadLetterExchangeName;

    @Bean
    @ConfigurationProperties("rabbit-service.common-orders")
    public RabbitProperties commonOrdersRabbitProperties() {
        return new RabbitProperties();
    }

    @Bean
    @ConfigurationProperties("rabbit-service.metrics")
    public RabbitProperties metricsRabbitProperties() {
        return new RabbitProperties();
    }

    ...//more beans
}

Configuration在另一个配置类中使用它:

@Configuration
@RequiredArgsConstructor
public class RabbitServiceConfig {

    private final RabbitProperties commonOrdersRabbitProperties;
    private final RabbitProperties metricsRabbitProperties;
    ...//about 15 similar fields

    
    @Bean("metricsRabbitService")
    public RabbitService getMetricsRabbitService(AmqpAdmin amqpAdmin, Client rabbitClient) {
        return new RabbitService(
                metricsRabbitProperties.getRequestExchangeName(),
                metricsRabbitProperties.getRequestQueueName(),
                metricsRabbitProperties.getResponseExchangeName(),
                metricsRabbitProperties.getDeadLetterExchangeName(),
                rabbitClient,
                amqpAdmin
        );
    }

    @Bean("commonOrdersRabbitService")
    public RabbitService getCommonOrdersRabbitService(AmqpAdmin amqpAdmin, Client rabbitClient) {
        return new RabbitService(
                commonOrdersRabbitProperties.getRequestExchangeName(),
                commonOrdersRabbitProperties.getRequestQueueName(),
                commonOrdersRabbitProperties.getResponseExchangeName(),
                commonOrdersRabbitProperties.getDeadLetterExchangeName(),
                rabbitClient,
                amqpAdmin
        );
    }
...//etc

RabbitProperties几乎每周都会添加新字段,所以现在它已经有大约 15-20 个相同的字段。我怎样才能摆脱这些领域并将它们放在Map例如?我应该把值放在哪里Map并初始化它?在这里使用的正确方法是什么ConfigurationProperties

标签: javaspringspring-boot

解决方案


如果我正确理解了这个问题,您可以private final Map<String, RabbitProperties> rabbitPropertiesMap;RabbitServiceConfig类中定义 a 而不是所有字段。所有的RabbitProperties都将通过注入在映射中绑定,键等于 bean 名称。

另一种不同的方法是RabbitProperties用类似的东西更新实现

@ConfigurationProperties("rabbit-service")
@Value
@ConstructorBinding
public class RabbitServiceProperties {

  Map<String, RabbitProperties> rabbitPropertiesMap;

  @Value
  static class RabbitProperties {

    String requestExchangeName;
    String requestQueueName;
    String responseExchangeName;
    String deadLetterExchangeName;
  }
}

这样,rabbit-service将发现并绑定 application.yml 中具有所描述结构的根目录下的所有内容。


推荐阅读