小马哥课程笔记
构造器注入 VS. Setter 注入
Spring Framework 对构造器注入与 Setter 的论点:
“The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the 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 MBeans is therefore a compelling use case for setter injection.”
《Expert One-on-One™ J2EE™ Development without EJB™》认为 Setter 注入的优点: “Advantages of Setter Injection include:
- JavaBean properties are well supported in IDEs. • JavaBean properties are self-documenting.
- JavaBean properties are inherited by subclasses without the need for any code.
- It’s possible to use the standard JavaBeans property-editor machinery for type conversions if necessary.
- Many existing JavaBeans can be used within a JavaBean-oriented IoC container without modification.
- If there is a corresponding getter for each setter (making the property readable, as well as writable), it is possible to ask the component for its current configuration state. This is particularly useful if we want to persist that state: for example,in an XML form or in a database. With Constructor Injection, there’s no way to find the current state.
- Setter Injection works well for objects that have default values, meaning that not all properties need to be supplied at runtime.”
《Expert One-on-One™ J2EE™ Development without EJB™》认为 Setter 注入的缺点: “Disadvantages include:
The order in which setters are called is not expressed in any contract. Thus, we sometimes need to invoke a method after the last setter has been called to initialize the component. Spring provides the
org.springframework.beans.factory.InitializingBean interface for this; it also provides the ability to invoke an arbitrary init method. However, this contract must be documented to ensure correct use outside a container.
Not all the necessary setters may have been called before use. The object can thus be left partially configured.”
《Expert One-on-One™ J2EE™ Development without EJB™》认为构造器注入的优点: “Advantages of Constructor Injection include:
Each managed object is guaranteed to be in a consistent state—fully configured—before it can be invoked in any business methods. This is the primary motivation of Constructor Injection. (However, it is possible to achieve the same result with JavaBeans via dependency checking, as Spring can optionally perform.) There’s no need for initialization methods.
There may be slightly less code than results from the use of multiple JavaBean methods, although will be no difference in complexity.”
《Expert One-on-One™ J2EE™ Development without EJB™》认为构造器注入的缺点: “Disadvantages include:
- Although also a Java-language feature, multi-argument constructors are probably less common in existing code than use of JavaBean properties.
- Java constructor arguments don’t have names visible by introspection.
- Constructor argument lists are less well supported by IDEs than JavaBean setter methods.
- Long constructor argument lists and large constructor bodies can become unwieldy.
- Concrete inheritance can become problematic.
- Poor support for optional properties, compared to JavaBeans
- Unit testing can be slightly more difficult
- When collaborators are passed in on object construction, it becomes impossible to change the reference held in the object. ”