结构体注入,setter注入是比较常用的依赖注入方式,都有各自的优缺点。setter注入是Spring推荐的依赖注入方式。
首先结构体注入有什么问题?
1. 不能重新配置和重新注入
在Spring参考文档 中基于结构体注入和setter注入有以下陈述:
Spring团队通常主张使用setter注入,因为大量的的结构体参数可能会使结构体变得笨重,特别是有些属性是可选的时候。相反setter注入可使对象在以后进行重新配置和重新注入。JMX管理MBean便是一个很好的例子。
一些纯粹主义者喜欢基于结构体注入。在实例化对象时提供所有对象依赖关系,这意味着对象总是以完全初始化的状态返回个客户端。缺点是对象变得不太适合重新配置和注入。
有时,在处理没有源代码的第三方类时,遗留的类可能不会公开任何setter方法,所以结构体注入是唯一可用的注入方式。因此,在没有sette存在的情况下,使用结构体注入,结构体注入不能通过正注入行的依赖项来重行配置构造的bean.如果需要重行配置bean,则必须使用新的依赖关系构建新的bean实例,并丢弃另一个。
2.循环依赖
Spring参考文档关于循环依赖有如下陈述:
如果主要使用结构体注入,则可能创建爱你一个无法解决的循环依赖的情况。
例如类A实例化时需要一个B实例,B实例化时需要一个A实例。如果将类A和B的bean配置为彼此注入,则Spirng Ioc 容器会在运行时检测此循环引用,并抛出一个BeanCurrentlyInCreationException。
一个可能的解决方案是编辑某些类的源代码通过setter注入而不是构造函数注入。或者,避免构造器注入和仅使用setter注入。换句话说,虽然不推荐,您可以使用setter注入来配置循环依赖关系.
与典型的情况(没有循环依赖)不同,bean A和bean B之间的循环依赖关系强制其中一个bean在被完全初始化之前被注入另一个bean(一个经典的鸡/鸡蛋场景)
需要注意的是setter注入也是一样的。当你有一个凌乱的构造函数或很多设置器,这意味着你的类设计和你的关注点是错误的。可能,您需要将一些行为重构到一个单独的类中。顺便说一下,字段注入会导致单元测试变得更加困难。使用构造函数或setter注入,您可以从单元测试中定义依赖关系,并将其传递给构造函数或setter方法。
结机构提注入用于强制性依赖关系和setter是可选注入,但是要确保构造函数不会乱成一团,也不会导致大量setter的出现。如果是这样的话,请注意分离关注点。
原文链接https://steveschols.wordpress.com/2012/06/05/i-was-wrong-constructor-vs-setter-injection/