Using Spring Dependency Injection we can remove the hard-coded dependencies from our code and dependences can be resolved at run-time instead of compile-time.
In few years ago, we were working in a project which was implemented for two countries. Almost all the modules were same apart from one module -tax calculation.
The plan was instead of packaging twice for two different countries, we will package the project only once for both the countries.
So we had one TaxCalculationService
interface with one method calculateTax(...)
Two different TaxCalculationServiceImpl
classes for two countries which implements TaxCalculationService
interface
Just like below
TaxCalculationServiceImplForCountryA implements TaxCalculationService
TaxCalculationServiceImplForCountryB implements TaxCalculationService
We called the calculateTax(...)
method from our manager class(TaxCalculationManagerImpl
).
And we had spring configuration file which is kept in an folder out side the war let say /home/config/
Both the war deployed into two different server.Same war, packaged once, only difference is in spring configuration file.
<!-- For country A-->
<bean id="taxCalculationService" class="com.TaxCalculationServiceImplForCountryA"/>
<bean id="taxCalculationManager" class="com.TaxCalculationManagerImpl">
<property name="taxCalculationService" ref="taxCalculationService"/>
</bean>
For Country B we need to modify the class name with bean id "taxCalculationService
", nothing else
<!-- For country B-->
<bean id="taxCalculationService" class="com.TaxCalculationServiceImplForCountryB"/>
<bean id="taxCalculationManager" class="com.TaxCalculationManagerImpl">
<property name="taxCalculationService" ref="taxCalculationService"/>
</bean>
So without doing recompile, packaging we easily used the same application war for both the countries, only changed the spring configuration file.
But in Spring - Java Based Configuration, if we want to implement same scenario, how we are going to do that?
While we are creating a bean we are using new operator to create a specific implementation class.
If we use the same interface TaxCalculationService
and TaxCalculationServiceImplForCountryA
class for country A then we have to something like
@Bean
public TaxCalculationService getTaxCalculationService(){
return new TaxCalculationServiceImplForCountryA();
}
For country B we need to do something like this
@Bean
public TaxCalculationService getTaxCalculationService(){
return new TaxCalculationServiceImplForCountryB();
}
So in this case we need to use new operator to create a specific implementation class of TaxCalculationService for a specific country. So what ever the flexibility we had in our xml based spring configuration, with out re-compiling, packaging the war, we reused the war, that can not be achieve in Java Based Configuration approach.
taxCalculationManager is dependent on taxCalculationService and whether taxCalculationManager is going invoke the calculateTax(...) of TaxCalculationServiceImplForCountryA or TaxCalculationServiceImplForCountryB that will be decided at run-time in xml based spring configuration.
But when we have to specify in the java code that the getTaxCalculationService() will return new TaxCalculationServiceImplForCountryA() or new TaxCalculationServiceImplForCountryB() then it is basically not resolving at the run-time.
So the dependency of taxCalculationManager on taxCalculationService is not resolving at run-time, it is basically resolving at compile time.
So don't you think in Spring - Java Based Configuration the beauty of Spring DI -resolving dependences at run-time instead of compile-time has lost?