Merge pull request #466 from olivergierke/SPR-11459

* SPR-11459:
  Update ref. manual to favor constructor injection
master
Sam Brannen 11 years ago
commit 1d47034736
  1. 62
      src/asciidoc/index.adoc

@ -1925,36 +1925,42 @@ on container specific interfaces, base classes or annotations.
}
----
The `ApplicationContext` supports constructor- and setter-based DI for the beans it
manages. It also supports setter-based DI after some dependencies are already injected
through the constructor approach. You configure the dependencies in the form of a
`BeanDefinition`, which you use with `PropertyEditor` instances to convert properties
from one format to another. However, most Spring users do not work with these classes
directly (programmatically), but rather with an XML definition file that is then
converted internally into instances of these classes, and used to load an entire Spring
IoC container instance.
The `ApplicationContext` supports constructor-based and setter-based DI for the beans it
manages. It also supports setter-based DI after some dependencies have already been
injected through the constructor approach. You configure the dependencies in the form of
a `BeanDefinition`, which you use in conjunction with `PropertyEditor` instances to
convert properties from one format to another. However, most Spring users do not work
with these classes directly (i.e., programmatically) but rather with XML `bean`
definitions, annotated components (i.e., classes annotated with `@Component`,
`@Controller`, etc.), or `@Bean` methods in Java-based `@Configuration` classes. These
sources are then converted internally into instances of `BeanDefinition` and used to
load an entire Spring IoC container instance.
.Constructor-based or setter-based DI?
****
Since you can mix both, Constructor- and Setter-based DI, it is a good rule of thumb to
use constructor arguments for mandatory dependencies and setters for optional
dependencies. Note that the use of a <<beans-required-annotation,@Required>> annotation
on a setter can be used to make setters required dependencies.
The Spring team generally advocates setter injection, because large numbers of
constructor arguments can get unwieldy, especially when properties are optional. Setter
methods also make objects of that class amenable to reconfiguration or re-injection
later. Management through <<jmx,JMX MBeans>> is a compelling use case.
Some purists favor constructor-based injection. Supplying all object dependencies means
that the object is always returned to client (calling) code in a totally initialized
state. The disadvantage is that the object becomes less amenable to reconfiguration and
re-injection.
Use the DI that makes the most sense for a particular class. Sometimes, when dealing
with third-party classes to which you do not have the source, the choice is made for
you. A legacy class may not expose any setter methods, and so constructor injection is
the only available DI.
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to
use constructors for _mandatory dependencies_ and setter methods or configuration methods
for _optional dependencies_. Note that use of the <<beans-required-annotation,@Required>>
annotation on a setter method can be used to make the property a required dependency.
The Spring team generally advocates constructor injection as it enables one to implement
application components as _immutable objects_ and to ensure that required dependencies
are not `null`. Furthermore constructor-injected components are always returned to client
(calling) code in a fully initialized state. As a side note, a large number of constructor
arguments is a _bad code smell_, implying that the class likely has too many
responsibilities and should be refactored to better address proper separation of concerns.
Setter injection should primarily only be used for optional dependencies that can be
assigned reasonable default values within the class. Otherwise, not-null checks must be
performed everywhere the code uses the dependency. One benefit of setter injection is that
setter methods make objects of that class amenable to reconfiguration or re-injection
later. Management through <<jmx,JMX MBeans>> is therefore a compelling use case for setter
injection.
Use the DI style that makes the most sense for a particular class. Sometimes, when dealing
with third-party classes for which you do not have the source, the choice is made for you.
For example, if a third-party class does not expose any setter methods, then constructor
injection may be the only available form of DI.
****
@ -1963,7 +1969,7 @@ the only available DI.
The container performs bean dependency resolution as follows:
* The `ApplicationContext` is created and initialized with configuration metadata that
describes all the beans. Configuration metadata can be specified via XML, Java code or
describes all the beans. Configuration metadata can be specified via XML, Java code, or
annotations.
* For each bean, its dependencies are expressed in the form of properties, constructor
arguments, or arguments to the static-factory method if you are using that instead of

Loading…
Cancel
Save