I have a service interface
interface ImageSearchService {
   // methods...
}
And I have 2 implementations:
@Service
class GoogleImageSearchImpl implements ImageSearchService {
   // methods...
}
@Service
class AzureImageSearchImpl implements ImageSearchService {
   // methods...
}
And I have a controller to use one of the both:
@Controller
ImageSearchController {
    @Autowired
    ImageSearchService imageSearch; // Google or Azure ?!?
}
How can I use a Environment API to set the right one implementation?
If environment property is my.search.impl=google spring needs to use GoogleImageSearchImpl, or if environment my.search.impl=google spring needs to use AzureImageSearchImpl.
You can achieve this using Spring Profiles.
interface ImageSearchService {}
class GoogleImageSearchImpl implements ImageSearchService {}
class AzureImageSearchImpl implements ImageSearchService {}
Note that the @Service annotation has been removed from both the implementation classes because we will instantiate these dynamically.
Then, in your configuration do this:
<beans>
  <beans profile="azure">
    <bean class="AzureImageSearchImpl"/>
  </beans>
  <beans profile="google">
    <bean class="GoogleImageSearchImpl"/>
  </beans>
</beans>
If you use Java configuration:
@Configuration
@Profile("azure")
public class AzureConfiguration {
  @Bean
  public ImageSearchService imageSearchService() {
    return new AzureImageSearchImpl();
  }
}
@Configuration
@Profile("google")
public class GoogleConfiguration {
  @Bean
  public ImageSearchService imageSearchService() {
    return new GoogleImageSearchImpl();
  }
}
When running the application, select the profile you want to run as by setting the value for the variable spring.profiles.active.  You can pass it to the JVM as -Dspring.profiles.active=azure, configure it as an environment variable, etc.
Here is a sample application that shows Spring Profiles in action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With