information required by the NewsletterSender, but the MessageProvider is really
another component that the MessageRenderer needs to function correctly.
Configuration parameters are usually simple values or collections of simple
values. This is really a by-product of the previous two points, but configuration
parameters are usually simple values. In Java this means they are a primitive (or
the corresponding wrapper class) or a String or collections of these values. Simple
values are generally passive. This means you can't do much with a String other
than manipulate the data it represents; and you almost always use these values for
information purposes--for example, an int value that represents the port number
that a network socket should listen on, or a String that represents the SMTP server
through which an e-mail program should send messages.
When considering whether to define configuration options in the business interface, also consider
whether the configuration parameter is applicable to all implementations of the business interface or
just one. For instance, in the case of implementations of NewsletterSender, it is obvious that all
implementations need to know which SMTP server to use when sending e-mails. However, we would
probably choose to leave the configuration option that flags whether to send secure e-mail off the
business interface, because not all e-mail APIs are capable of this, and it is correct to assume that many
implementations will not take security into consideration at all.
■ Note Recall that in Chapter 2, we chose to define the dependencies in the business purposes. This was for
illustration purposes and should not be treated in any way as a best practice.
Setter injection also allows you to swap dependencies for a different implementation on the fly
without creating a new instance of the parent component. Spring's JMX support makes this possible.
Perhaps the biggest benefit of Setter Injection is that it is the least intrusive of the injection mechanisms.
If you are defining constructors for injection on a class that would otherwise just have the default
constructor, then you are affecting all code that uses that class in a non-IoC environment. Extra setters
that are defined on a class for IoC purposes do not affect the ability of other classes to interact with it.
In general, setter-based injection is the best choice, because it has the least effect on your code's
usability in non-IoC settings. Constructor injection is a good choice when you want to ensure that
dependencies are being passed to a component, but bear in mind that many containers provide their
own mechanism for doing this with Setter Injection. Most of the code in the sample application uses
Setter Injection, although there are a few examples of Constructor Injection.
Inversion of Control in Spring
As we mentioned earlier, Inversion of Control is a big part of what Spring does, and the core of Spring's
implementation is based on Dependency Injection, although Dependency Lookup features are provided
as well. When Spring provides collaborators to a dependent object automatically, it does so using
Dependency Injection. In a Spring-based application, it is always preferable to use Dependency
Injection to pass collaborators to dependent objects rather than have the dependent objects obtain the
collaborators via lookup. Figure 4-3 shows Spring's Dependency Injection mechanism (for Dependency
Lookup, please refer to Figure 4-2).
Search WWH :