Issue
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?
Solution
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.
Answered By - spa
Answer Checked By - Terry (JavaFixing Volunteer)