简体   繁体   中英

Spring - Inject Dependency based on properties

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.

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

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

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM