Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring multiple @ConfigurationProperties with same class

I have a class of the sort :

@Data
@Component
@ConfigurationProperties("a.config.props")
public class ClientProperties {

    private String hostname;
    private String port;
    private String baseUrl;
    private String endpoint;
}

I have tens of property contexts but for 1 line i have to repeat the whole class. Is there a simple and elegant way to have one class and somehow pass the property context dynamically (maybe an array or something of the sort) so that i use the same class.

like image 455
Raghuveer Avatar asked Aug 22 '19 18:08

Raghuveer


People also ask

Can we have multiple @configuration in Spring?

Yes, we can have more than one spring context files. The following are the 2 ways to configure multiple context files.

What is the use of @configuration in Spring boot?

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

What are the ways in which Spring boot can read configuration?

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration.

How do you read application properties in Spring boot main class?

Another very simple way to read application properties is to use @Value annotation. Simply annotation the class field with @Value annotation providing the name of the property you want to read from application. properties file and class field variable will be assigned that value.


2 Answers

You can just have a single class that describes your numerous & identical property blocks;

@Data
public class ClientProperties {
    private String hostname;
    private String port;
    private String baseUrl;
    private String endpoint;
}

Then refer to it as such to link that single class with different property blocks;

@Configuration
public class PropertyConfigurer {

    @Bean
    @ConfigurationProperties("props.one")
    private ClientProperties propsOne() {
        return new ClientProperties();
    }

    @Bean
    @ConfigurationProperties("props.two")
    private ClientProperties propsTwo() {
        return new ClientProperties();
    }

    @Bean
    @ConfigurationProperties("props.three")
    private ClientProperties propsThree() {
        return new ClientProperties();
    }
}

Then you can access them via their method names as qualifiers;

@Component
public class SomeService {

    @Autowired
    private ClientProperties propsOne;
    @Autowired
    private ClientProperties propsTwo;
    @Autowired
    private ClientProperties propsThree;

    ... some logic
}
like image 190
buræquete Avatar answered Oct 18 '22 01:10

buræquete


I would suggest to create an abstract class with all the properties and extend the abstract class for as many property variants you have.

@Data
public abstract class BaseClientProperties {
    private String hostname;
    private String port;
    private String baseUrl;
    private String endpoint;
}

@Configuration
@ConfigurationProperties("a.config.props1")
public class Client1Properties extends BaseClientProperties{

}

@Configuration
@ConfigurationProperties("a.config.props2")
public class Client2Properties extends BaseClientProperties{
}

Use them as below:

@Service
public class SomeService {

    @Autowired
    private Client1Properties client1Properties;
    @Autowired
    private Client2Properties client2Properties;

    ... service logic
}
like image 3
Sumant Avatar answered Oct 17 '22 23:10

Sumant