Инъекция зависимостей, зависящая от аннотаций, которая обрабатывает различные среды

Я думаю, что основная причина, почему многие профессионалы не переключились на введение зависимостей, зависящих от аннотаций, заключается в том, что она не поддерживает переключение между средами разработки/тестирования/производства. В целях развития во многих случаях вы используете не только разные службы (и соединения для них), но иногда вам нужно их имитировать или создавать экземпляры Dummy.

Вчера я выяснил одно решение с аннотацией Spring:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

... который должен работать, но не приятно.

Я бы очень интересовался вашими решениями или аргументами: почему это не настоящая проблема;-) Guice, Spring или любой другой приветствуются.

Исходная проблема была частью этого потока: Spring @Возможное использование, но я подумал, что стоит создать новый поток.

Ответ 1

К сожалению, я не могу комментировать Guice, но, как упоминалось в комментариях, вы действительно можете использовать профили Spring - если вы используете Spring 3.1 или новее.

Конфигурация на основе Java с использованием профилей может выглядеть примерно так:

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

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

Затем ваш потребительский класс снова станет проще:

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

Желаемый профиль может, среди прочего, активироваться через системное свойство:

-Dspring.profiles.active="production"

Что может быть полезно при запуске приложения в разных средах.

Лично я стараюсь вообще не полагаться на профили Spring. Вместо этого я пытаюсь инкапсулировать экологические различия во внешних файлах свойств, которые передаются приложению во время выполнения. До сих пор этот подход работал хорошо, но ymmv.

Ответ 2

@Value аннотация не работает так, как вы пробовали. Он может давать только значения в виде строки. Для чего вы хотите достичь, вы можете попробовать Spring Профили, как предложено @ShyJ.

Надеюсь, это поможет вам. Приветствия.