0

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.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
zlekonis
  • 31
  • 6
  • Do you have to use properties files, or can you use YAML? Spring supports both. – E-Riz Nov 29 '22 at 14:17
  • @E-Riz Prefer properties files – zlekonis Nov 30 '22 at 12:39
  • One solution I can think of uses Spring config profiles, which can be specified in a variety of ways. Any objection to using them? If not, I'll write up an answer for that. – E-Riz Nov 30 '22 at 14:48
  • @E-Riz Yes, I was thinking about using profiles as well, since before startup I know the amount and exact properties files which were added before. This is achievable with profiles, but I prefer not using them for this case and keeping profiles for separating environments instead (dev,test,prod) etc. Adding multiple non-environment values as profiles will start to be messy. Think of having like 100~ or more ANIMAL.animal.properties – zlekonis Nov 30 '22 at 14:54
  • I thought so, too. That's why I asked before writing the idea as an answer. – E-Riz Nov 30 '22 at 15:38

1 Answers1

0

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"

  • Thanks for help, but this is already contradicting what I want to do on my Step1. Using environment properties and having defined number of properties files (with dynamic names from env) is exactly opposite what I need. As I mentioned, I cannot use PropertySource annotation, due to it's need for static values or placeholders. What I'm trying to achieve probably requires going more deep into configuration adjustment on startup. – zlekonis Nov 30 '22 at 12:43