Annotation-driven dependency injection which handles different environments

annotations, dependency-injection, guice, java, spring

Solution

Unfortunately I cannot comment on Guice, but as mentioned in the comments you can indeed use Spring profiles - if you're using Spring 3.1 or later that is.

A Java based configuration using profiles could look something like:

@Configuration
@Profile("production")
public class ProductionConfig {
    @Bean 
    public SomeService someService() { ... }
}

@Configuration
@Profile("dev")
public class DevelopmentConfig {
    @Bean 
    public SomeService someService() { ... }
}

Then your consuming class then becomes simpler again:

...
@Autowired
private SomeService someService;
...

The desired profile can, amongst other ways, be activated through a system property:

-Dspring.profiles.active="production"

Which can be useful when running your application in different environments.

Personally I try not to rely on Spring profiles at all. Instead I try and encapsulate environmental differences in external property files, which are passed to the application at runtime. This approach has worked well so far but ymmv.

Problem

I think the main reason why many professional does not switch to annotation-driven dependency injection is that it does not support switching between development/test/production environments. For development purposes in many cases you use not only different services (and connections for them), but sometimes you need to Mock them, or create Dummy instances. Yesterday I figured out one solution with Spring annotation: ``` @Value("#{${env} == "production" ? realService : dummyService}") private SomeService service; ``` ...which should work, but not nice. I would be very interested for your solutions, or arguments: why is it not a real issue ;-) Guice, Spring, or any other are welcome. The original issue was a part of this thread: Spring @Autowired usage, but I thought it worth a new thread to be created.

Original source