Listing 2-6.Example B
<bean id="addressService" class="org.example.addr.AddressServiceImpl">
<property name="zipCodeService" ref="zipCodeService" />
<property name="postalServiceValidator" ref="uspsValidator" />
<property name="mappingService" ref="googleMapService" />
</bean>
You don’t have to know how to read Spring’s bean definition XML format to tell which
configuration exposes more information. Example B uses setter-based injection, clearly
indicating which properties have which value.
The choice of Dependency Injection methods is yours; feel free to mix and match the two
approaches in your application.
The main point is that the framework is responsible for wiring the application together,
before the application starts. Dependencies are injected into objects without those objects
actively requesting anything. Another benefit of Dependency Injection is the client doesn’t
know the details of the physical implementation of the dependency. In other words, the client
code is not coupled to any concrete implementation. As long as the dependency implements
the interface requested, the contract is fulfilled.
Unit Testing Benefits
Dependency Injection easily solves our concern of testability. By using a setter method and
removing the Service Locator (potentially removing tremendous amounts of JNDI code), we’ve
divorced our CashRegisterImplobject from any sort of environment prerequisite. This means
we can easily run CashRegisterImploutside of any container and even independently of the
framework itself.
The following JUnit test example illustrates how easy it is to test a method that doesn’t use
a Service Locator. The code creates a mock to stand in for a real PriceMatrix. The mock then is
set into the CashRegisterImplclass we are testing. This isolates our class so that the only code
that is being tested is the CashRegisterImpl. All dependencies are under our control, through
their mock replacements.
public void testCalculateTotalPrice() {
Mock mockPriceMatrix = mock(PriceMatrix.class);
PriceMatrix priceMatrix = (PriceMatrix) mockPriceMatrix.proxy();
cashRegister.setPriceMatrix(PriceMatrix);
// mock object expectations set...
assertEquals(42.00, cashRegister.calculateTotalPrice(cart));
}
In the context of a unit test, the framework itself is absent. There’s no mention of Spring.
That’s what we call lightweight.
Summary
Dependency Injection is a technique to wire an application together without any participation
by the code that requires the dependency. The client usually exposes setter methods so that
the framework may inject any needed dependencies. The client now allows others to manage
16 CHAPTER 2 ■SPRING FUNDAMENTALS