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 The `ApplicationContext` supports constructor-based and setter-based DI for the beans it
manages. It also supports setter-based DI after some dependencies are already injected manages. It also supports setter-based DI after some dependencies have already been
through the constructor approach. You configure the dependencies in the form of a injected through the constructor approach. You configure the dependencies in the form of
`BeanDefinition`, which you use with `PropertyEditor` instances to convert properties a `BeanDefinition`, which you use in conjunction with `PropertyEditor` instances to
from one format to another. However, most Spring users do not work with these classes convert properties from one format to another. However, most Spring users do not work
directly (programmatically), but rather with an XML definition file that is then with these classes directly (i.e., programmatically) but rather with XML `bean`
converted internally into instances of these classes, and used to load an entire Spring definitions, annotated components (i.e., classes annotated with `@Component`,
IoC container instance. `@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? .Constructor-based or setter-based DI?
**** ****
Since you can mix both, Constructor- and Setter-based DI, it is a good rule of thumb to Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to
use constructor arguments for mandatory dependencies and setters for optional use constructors for _mandatory dependencies_ and setter methods or configuration methods
dependencies. Note that the use of a <<beans-required-annotation,@Required>> annotation for _optional dependencies_. Note that use of the <<beans-required-annotation,@Required>>
on a setter can be used to make setters required dependencies. annotation on a setter method can be used to make the property a required dependency.
The Spring team generally advocates setter injection, because large numbers of The Spring team generally advocates constructor injection as it enables one to implement
constructor arguments can get unwieldy, especially when properties are optional. Setter application components as _immutable objects_ and to ensure that required dependencies
methods also make objects of that class amenable to reconfiguration or re-injection are not `null`. Furthermore constructor-injected components are always returned to client
later. Management through <<jmx,JMX MBeans>> is a compelling use case. (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
Some purists favor constructor-based injection. Supplying all object dependencies means responsibilities and should be refactored to better address proper separation of concerns.
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 Setter injection should primarily only be used for optional dependencies that can be
re-injection. 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
Use the DI that makes the most sense for a particular class. Sometimes, when dealing setter methods make objects of that class amenable to reconfiguration or re-injection
with third-party classes to which you do not have the source, the choice is made for later. Management through <<jmx,JMX MBeans>> is therefore a compelling use case for setter
you. A legacy class may not expose any setter methods, and so constructor injection is injection.
the only available DI.
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 container performs bean dependency resolution as follows:
* The `ApplicationContext` is created and initialized with configuration metadata that * 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. annotations.
* For each bean, its dependencies are expressed in the form of properties, constructor * 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 arguments, or arguments to the static-factory method if you are using that instead of

Loading…
Cancel
Save