1

Suppose I have an interface (Note: Object is used for example simplicity, not in practice)

public interface IObjectGenerator {
    public List<Object> getObjectsFromThing(String thing);
}

and multiple implementations of this interface

@Service
public class FromFileObjectGenerator implements IObjectGenerator {
    // File interaction supporting vars and functions

    public List<Object> getObjectsFromThing(String thing){
        // Use file stuff to generate and return list of objects
    }
}

@Service
public class FromDatabaseObjectGenerator implements IObjectGenerator {
    // DB interaction supporting vars and functions
    
    public List<Object> getObjectsFromThing(String thing) {
        // Use DB stuff to generate and return list of objects
    }
}

@Service
public class FromWebObjectGenerator implements IObjectGenerator {
    // Web interaction supporting vars and functions
    
    public List<Object> getObjectsFromThing(String thing) {
        // Use Web stuff to generate and return list of objects
    }
}

Sometimes I only want to leverage the file based generator, sometimes the file and db, or db and web, or all of them, etc.

So, I think I need to be able to set which implementations to inject, from at least one of them, up to all of them (and any that may be created in the future), and any combination in between. This needs to be done in configuration file (like application.properties).

public class GeneratorUser {
    private List<IObjectGenerator> generators;

    @Autowired
    public GeneratorUser(List<IObjectGenerator> generators){
        this.generators = generators;
    }
}

I've seen the possibility of making an overarching management class that instantiates all of the generator, injecting the management class, and have it only return the generators necessary when queried, but I'd prefer to prevent instantiating the unused generators at all if possible. Is there an easy way to go about this?

1
  • 1
    If the unused generators are never instantiated, they wouldn't exist as beans in the Spring application context, so they can never be used. Commented Oct 5, 2022 at 18:17

1 Answer 1

3

This is actually quite simple. The term here is "Conditional beans".

@Service
@ConditionalOnProperty(value="a.b.c", havingValue = "true")
public class FromFileObjectGenerator implements IObjectGenerator {
   //
}

This will tell the system to only create the bean if the key "a.b.c" in the application.properties is set to "true". There are a lot more @ConditionalOn... annotations, check https://www.baeldung.com/spring-conditional-annotations.

Sign up to request clarification or add additional context in comments.

3 Comments

Just to make sure I'm following, this would necessitate having a key for each generator right?
If you want to control all individually of course. However, there's no one preventing you to use the same key for multiple beans - they will be turned on/off as group then.
I also saw you can define custom conditionals that employ some logic, so perhaps I can configure a list of "keys" and check if the one relevant to the bean is present in that list as the condition

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.