Потеряна ли прелесть зависимостей Spring DI во время выполнения вместо времени компиляции в конфигурации на основе Java?
Используя Spring Dependency Injection, мы можем удалить жестко запрограммированные зависимости из нашего кода, и зависимости могут быть разрешены во время выполнения, а не во время компиляции.
Несколько лет назад мы работали над проектом, который был реализован для двух стран. Практически все модули были одинаковыми, кроме одного модуля - расчета налога.
План был вместо упаковки дважды для двух разных стран, мы будем упаковывать проект только один раз для обеих стран.
Итак, у нас был один TaxCalculationService
интерфейс с одним методом calculateTax(...)
Два разных TaxCalculationServiceImpl
классы для двух стран, которая реализует TaxCalculationService
интерфейс
Прямо как ниже
TaxCalculationServiceImplForCountryA implements TaxCalculationService
TaxCalculationServiceImplForCountryB implements TaxCalculationService
Мы назвали calculateTax(...)
метод из нашего класса менеджера (TaxCalculationManagerImpl
).
И у нас был весенний конфигурационный файл, который хранится в папке вне войны, скажем /home/config/
Обе войны развернуты на двух разных серверах. Одна и та же война, упакованная один раз, единственное отличие заключается в весеннем конфигурационном файле.
<!-- For country A-->
<bean id="taxCalculationService" class="com.TaxCalculationServiceImplForCountryA"/>
<bean id="taxCalculationManager" class="com.TaxCalculationManagerImpl">
<property name="taxCalculationService" ref="taxCalculationService"/>
</bean>
Для страны B нам нужно изменить имя класса с помощью идентификатора компонента "taxCalculationService
", ничего больше
<!-- For country B-->
<bean id="taxCalculationService" class="com.TaxCalculationServiceImplForCountryB"/>
<bean id="taxCalculationManager" class="com.TaxCalculationManagerImpl">
<property name="taxCalculationService" ref="taxCalculationService"/>
</bean>
Поэтому, не выполняя перекомпиляцию, мы легко использовали одну и ту же войну приложений для обеих стран, изменив только конфигурационный файл Spring.
Но в Spring - Java Based Configuration, если мы хотим реализовать тот же сценарий, как мы собираемся это сделать?
Пока мы создаем бин, мы используем оператор new для создания определенного класса реализации.
Если мы используем тот же интерфейс TaxCalculationService
а также TaxCalculationServiceImplForCountryA
класс для страны А, то мы должны что-то вроде
@Bean
public TaxCalculationService getTaxCalculationService(){
return new TaxCalculationServiceImplForCountryA();
}
Для страны B нам нужно сделать что-то вроде этого
@Bean
public TaxCalculationService getTaxCalculationService(){
return new TaxCalculationServiceImplForCountryB();
}
Поэтому в этом случае нам нужно использовать новый оператор для создания определенного класса реализации TaxCalculationService для конкретной страны. Так что, несмотря на всю гибкость, которую мы имели в нашей весенней конфигурации на основе xml, без перекомпиляции, упаковки войны, мы снова использовали войну, чего нельзя достичь в подходе Java Based Configuration.
taxCalculationManager зависит от taxCalculationService и от того, собирается ли taxCalculationManager вызывать возложить вычисление (...) из TaxCalculationServiceImplForCountryA или TaxCalculationServiceImplForCountryB, что будет принято во время выполнения в весенней конфигурации на основе xml.
Но когда мы должны указать в java-коде, что getTaxCalculationService() будет возвращать новый TaxCalculationServiceImplForCountryA() или новый TaxCalculationServiceImplForCountryB(), тогда это в основном не разрешается во время выполнения.
Таким образом, зависимость taxCalculationManager от taxCalculationService не разрешается во время выполнения, а в основном разрешается во время компиляции.
Так что вы не думаете, что в Spring - Java Based Configuration потеря разрешения DI -зависимостей Spring во время выполнения, а не во время компиляции?
1 ответ
Одним из возможных вариантов является использование Spring Profiles (@Profile
). На основе профиля, который вы настроили в файле конфигурации или передали в проект через системное свойство, вы можете активировать или деактивировать bean-компоненты.