2

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?

Betlista
  • 10,327
  • 13
  • 69
  • 110
Bacteria
  • 8,406
  • 10
  • 50
  • 67
  • 1
    No it hasn't... Just create 2 configuration and use profiles to load either one. This should also have been the approach with the xml based version. Also `@Configuration` classes are special classes in that they are processed using ASM to get the bean definitions. SO they aren't used as regular java classes. – M. Deinum Sep 04 '15 at 12:54

1 Answers1

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.

luboskrnac
  • 23,973
  • 10
  • 81
  • 92