How to dynamically provide different .properties files for beans of same type?

358 views Asked by At

Let's provide context, before I try to explain the need I'd want to meet.

Class - AnimalShelterConfiguration

@Configuration
public class AnimalShelterConfiguration {

    @Bean
    public List<Animal> animals(@Value("#{'${animals}'.split(',')}") List<String> animals) {
        return animals.stream()
                .map(animal -> animal())
                .collect(Collectors.toList());
    }

    @Bean
    public Animal animal() {
        return new Animal();
    }

}

Class - Animal

public class Animal {

    @Value("${name}")
    private String name;

}

Resources structure:
+ src/main/resources
+ animal.properties
+ animals/
+ dog.animal.properties
+ cat.animal.properties

animal.properties:
animals=dog,cat
dog.animal.properties:
name=dog
cat.animal.properties
name=cat

----

  1. Now, what I want to do is create as many Animal beans as it's defined in animal.properties. Each value in animals list should "refer" to matching ones in animals/ directory.
  2. Next, I want each bean to "take or be provided with" their own properties file and inject all properties from it into the bean. Each bean should have their own separate properties file as in animals/ directory. So, when a new beans of Animal are created, @Value("${name})resolved values should correspond to dogand caton different beans of same type.
  3. There could be any number of different ANIMAL.animal.properties - all animals are undefined and may be added on the animal list. However, list of property names inside ANIMAL.animal.properties are the same.

Is there any way to achieve this without much configuration using Spring Boot? As I know, ConfigurationProperties and PropertySource must contain a static value, so this is automatically unfit option for me. Can this be done using spring context while registering beans and providing different classes of PropertySourcePlaceholderConfigurer by scanning location using regex *.animal.properties somehow?

Any help is appreciated.

P.S. All these classes and properties are made-up, I just want to get the idea if this is possible.

1

There are 1 answers

1
Cristina Moretti On

You can use @ProperySource annotation

@PropertySource("classpath:foo.properties")

Or you can register a new properties file using a placeholder, which allows us to dynamically select the right file at runtime

@PropertySource({ 
  "classpath:persistence-${envTarget:mysql}.properties"
})

try searching for the topic "Properties with Spring and Spring Boot"