使用 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 使用相同的接口TaxCalculationService
和 TaxCalculationServiceImplForCountryA
类,那么我们必须像
@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 的美丽 - 在运行时而不是编译时解决依赖关系已经失去了吗?