2

使用 Spring Dependency Injection,我们可以从代码中删除硬编码的依赖关系,并且可以在运行时而不是编译时解决依赖关系

几年前,我们在一个为两个国家实施的项目中工作。除了一个模块 - 税收计算之外,几乎所有模块都是相同的。

该计划不是为两个不同的国家/地区打包两次,而是为这两个国家/地区仅打包一次项目。

所以我们有一个TaxCalculationService接口和一种方法calculateTax(...)

TaxCalculationServiceImpl实现TaxCalculationService接口的两个国家的两个不同的类

就像下面一样

TaxCalculationServiceImplForCountryA implements TaxCalculationService
TaxCalculationServiceImplForCountryB implements TaxCalculationService

calculateTax(...)我们从管理器类(TaxCalculationManagerImpl)中调用了该方法。

我们有spring配置文件,它保存在战争之外的一个文件夹中,比如说/home/config/

两个war部署到两个不同的服务器上。同一个war,打包一次,唯一不同的是spring配置文件。

<!-- For country A-->
<bean id="taxCalculationService" class="com.TaxCalculationServiceImplForCountryA"/>

<bean id="taxCalculationManager" class="com.TaxCalculationManagerImpl">
        <property name="taxCalculationService" ref="taxCalculationService"/>
</bean>

对于 B 国,我们需要用 bean id " 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 中,如果我们想实现相同的场景,我们将如何做到这一点?

在创建 bean 时,我们使用 new 运算符来创建特定的实现类

如果我们对国家 A 使用相同的接口TaxCalculationServiceTaxCalculationServiceImplForCountryA类,那么我们必须像

@Bean
public TaxCalculationService getTaxCalculationService(){             
    return new TaxCalculationServiceImplForCountryA();          
}

对于 B 国,我们需要做这样的事情

@Bean
public TaxCalculationService getTaxCalculationService(){
    return new TaxCalculationServiceImplForCountryB();
}

所以在这种情况下,我们需要使用new 运算符为特定国家创建一个特定的 TaxCalculationService 实现类因此,我们在基于 xml 的 spring 配置中拥有怎样的灵活性,无需重新编译、打包 war,我们重用了 war,这在基于 Java 的配置方法中是无法实现的。

taxCalculationManager 取决于 taxCalculationService 以及 taxCalculationManager 是否会调用 TaxCalculationServiceImplForCountryA 或 TaxCalculationServiceImplForCountryB 的 calculateTax(...) ,这将在运行时在基于 xml 的 spring 配置中决定。

但是,当我们必须在 java 代码中指定 getTaxCalculationService() 将返回 new TaxCalculationServiceImplForCountryA() 或 new TaxCalculationServiceImplForCountryB() 时,它基本上不会在运行时解析。

所以 taxCalculationManager 对 taxCalculationService 的依赖不是在运行时解决的,它基本上是在编译时解决的。

所以你不认为在Spring - Java Based Configuration 中 Spring DI 的美丽 - 在运行时而不是编译时解决依赖关系已经失去了吗?

4

1 回答 1

3

One possible option is to use Spring Profiles (@Profile). Based on profile you configured in configuration file or pass into project via system property, you can activate or deactivate beans.

于 2015-09-04T12:58:31.530 回答