构造器注入与Setter注入的区别

您所在的位置:网站首页 set注入和构造注入的区别 构造器注入与Setter注入的区别

构造器注入与Setter注入的区别

#构造器注入与Setter注入的区别| 来源: 网络整理| 查看: 265

本篇我们来一起讨论下构造器注入和Setter注入。这里我将以Spring官方网站和Spring的作者写过的一本书《J2EE Development without EJB》为蓝本来进行比较然后来看一下他们的观点。

首先我们来看Spring官方网站的对于构造器注入和Setter注入的阐述: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 MBeans is therefore a compelling use case for setter injection.

翻译成中文意思是:Spring团队通常是鼓励你使用构造器注入的。这里就隐含了一个意思,Spring允许你在进行业务开发的时候,你的业务对象是一个不变对象,来确保你的依赖不是为空的。另外通过构造器注入的对象通常是需要返回到客户端的,那么这个时候更需要注入返回的是一个完整的对象。另外一方面,如果通过构造器注入的对象有太多的职责的话,通常来说不是一个好的实现,我们需要将其重构。

关于Setter注入应该仅仅用于可选性的注入。这种讲法其实是对的,因为字段本身是允许变化的,因此对象本身它是可以为空的。另外一个Setter注入的好处是让对象变得更加灵活,因为我们可以重新配置或重新注入。

接下来我们再来看下《J2EE Development without EJB》这本书里面关于构造器注入和Setter注入的讨论。这本书认为Setter注入的有点有以下:

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.”

Setter注入的缺点: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.”

而关于构造器的优点: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.”

最后是构造器的缺点:

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. ”

以上就是关于构造器注入和Setter方法注入的区别,我个人认为这两本书已经讲解的非常详细了。这其实是一个见仁见智的问题,如果你要我选我个人偏好于选择构造器注入,因为构造器注入可以避免很多尴尬的问题,比如说状态不确定性地被修改,因为你也不知道你的小伙伴到什么时候会去调用Setter方法。所以说到底,我们更希望的是当我们的Bean初始化之后是不变的对象,这样的话对我们程序和维护性都会带来更多的便利。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3