Annotation-driven dependency injection which handl

2020-02-23 08:55发布

问题:

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.

回答1:

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.



回答2:

@Value annotation doesn't work the way you have tried. It can only give you values in form of String. For what you want to achieve you can try Spring Profiles as suggested by @ShyJ.

Hope this helps you. Cheers.