1

I have Properties class with a few different beans. Values from 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
}

I'm using this Configuration in another config class:

@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

I'm adding new RabbitProperties field almost every week, so now it already has about 15-20 kinda same fields. How can I get rid of these fields and put them to Map for example? Where should I put values for this Map and initialize it? What is the proper way to use ConfigurationProperties here?

1 Answer 1

3

If I've understood the question properly, you could define a private final Map<String, RabbitProperties> rabbitPropertiesMap; in the RabbitServiceConfig class instead of all the fields. All the RabbitProperties will be bounded in the map by injection, with key equals to bean name.

Another different approach would be to update the implementation of RabbitProperties with something like

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

  Map<String, RabbitProperties> rabbitPropertiesMap;

  @Value
  static class RabbitProperties {

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

this way everything under the root rabbit-service in the application.yml with the structure described will be discovered and bound.

Not the answer you're looking for? Browse other questions tagged or ask your own question.