Raghuveer
Raghuveer

Reputation: 3057

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.

Upvotes: 16

Views: 20023

Answers (3)

buræquete
buræquete

Reputation: 14678

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
}

Upvotes: 26

Sumant
Sumant

Reputation: 134

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
}

Upvotes: 7

Rob Scully
Rob Scully

Reputation: 790

Suppose you want hostname as a list to your properties file then you can rearrange your code like this:

@Component
@ConfigurationProperties("a.config.props")
@Data
public class ClientProperties {
    private List<String>  hostname;
    private String port;
    private String baseUrl;
    private String endpoint;
}

You can then place your configuration properties in your application.properties file like this:

a.config.props.hostname[0]=host1.com
a.config.props.hostname[1]=host2.com
a.config.props.hostname[2]=host3.com
a.config.props.port=8080
a.config.props.baseUrl=baseurl
a.config.props.endpoint=/thisendpoint

Then simply @Autowire your ClientProperties to the class you want and call

List<String> hostnames = clientProperties.getHostname();

You can utilize their values as required then. If I understand your question correctly I think this will answer it. Let me know if you need more information.

Upvotes: 0

Related Questions