Reputation: 26527
Does Spring Boot have a way to inject a dependency with the class name and constructor properties provided in the config file?
For example, I have two version of a common interface, IFileStore
, FileStoreA
and FileStoreB
. I want to be able to define which of these I should use in the application.yml
file.
I know I can do something like this:
@Value("${fileStore.class}")
private String fileStoreClassName;
@Bean
public IFileStore fileStore() {
switch(fileStoreClassName) {
case "FileStoreA":
return new FileStoreA();
case "FileStoreB":
return new FileStoreB();
}
}
This however feels really hacky. I'd also have to manually extract and supply any required parameters to them.
My ideal would be that it's able to determine which to use based on the class name, and also provide any parameters the specific one needs, so if I add a third FileStore
, it'd auto-magically work and I'd just have to use that for the class name instead.
Upvotes: 3
Views: 3289
Reputation: 4657
Are you perhaps looking for XML-based configuration?
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="fileStore" class="com.example.FileStoreA">
<property name="parameter1" value="Hello World!"/>
</bean>
</beans>
Upvotes: 0
Reputation: 11818
If you really only need a single bean, then create a conditional configuration
@Configuration
@ConditionalOnProperty(name = "fileStore.class", havingValue="FileStoreA")
public class FileStoreAConfiguration {
@Bean
public IFileStore fileStore() {
return new FileStoreA(...);
}
}
@Configuration
@ConditionalOnProperty(name = "fileStore.class", havingValue="FileStoreB")
public class FileStoreBConfiguration {
@Bean
public IFileStore fileStore() {
return new FileStoreB(...);
}
}
It's actually easier than that, as the annotation can be used on a method instead, rather than having separate configuration classes.
See the ConditionalOnProperty Javadoc
Upvotes: 3
Reputation: 3125
You can use Spring Profiles (@Profile
annotation) in order to configure the same @Bean but with different implementations.
For example, you can make a production configuration like this:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}
So, for your example, you can configure how many profiles you require and then you can specify the property in any of the usual ways, for example, you could include it in your application.properties
.
For further details, you can read Spring Boot features - Profiles
Upvotes: 1