Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不可变对象和Spring/SpringMVC:正确的选择?_Java_Spring_Spring Mvc - Fatal编程技术网

Java 不可变对象和Spring/SpringMVC:正确的选择?

Java 不可变对象和Spring/SpringMVC:正确的选择?,java,spring,spring-mvc,Java,Spring,Spring Mvc,我通常尝试将我的类设计为不可变类,因此在编码压力方面我有很多优势 但是使用Spring时,我有时会注意到框架在大多数情况下“不鼓励”这种设计,而支持经典的JavaBeans设计:默认构造函数+getter/setters 我真的不喜欢JavaBean设计的对象,因为它们具有疯狂的易变性。 所以我想知道我是否错过了什么 我试图让我的类设计尽可能优雅和可重用,但框架需要改变这种设计或以一种困难的方式允许它 这有什么问题?它使用依赖项注入将对象注入到其他对象中。所以,如果这些其他对象是不可变的,它就不

我通常尝试将我的类设计为不可变类,因此在编码压力方面我有很多优势

但是使用Spring时,我有时会注意到框架在大多数情况下“不鼓励”这种设计,而支持经典的JavaBeans设计:默认构造函数+getter/setters

我真的不喜欢JavaBean设计的对象,因为它们具有疯狂的易变性。 所以我想知道我是否错过了什么

我试图让我的类设计尽可能优雅和可重用,但框架需要改变这种设计或以一种困难的方式允许它


这有什么问题?

它使用依赖项注入将对象注入到其他对象中。所以,如果这些其他对象是不可变的,它就不能改变它们的状态

对于web表单数据绑定(即form POST),问题是Java反射在构造函数上很弱,因此在没有注释的情况下很难进行数据绑定。很久以前,我曾考虑提交一个bug,Springs数据绑定应该利用经常被遗忘的漏洞(iirc我曾亲自研究过做这个补丁,但它相当复杂,会破坏很多东西)。可能有人应该提交一个功能请求

顺便说一句,我说的是web数据绑定(而不是依赖项注入),因为Spring长期以来一直非常支持基于构造函数的DI(不可变对象需要基于构造函数的注入)。事实上,我想说基于构造函数的注入或(静态方法工厂)正在成为传统getter/setter组件的首选实践(您可以在许多Spring类中看到这一点,这些年来,它们朝着final和构造函数的方向发展)

无论如何,我能够使用Jackson与不可变对象进行web数据绑定

(尽管使用Jackson对请求进行数据绑定不必使用JSON)


您可能还想看看我最初提出的要点和更多信息。

我有时会创建单独的不可变“设计模型”类和可变(JavaBean)“MVC模型”类来避免这些问题。

Spring通常不会支持或阻止任何事情,所以我想知道您为什么会这样想。没有什么可以阻止您在bean中进行构造函数注入而不是setter注入(您也可以进行基于字段的注入)。唯一需要getter/setter的地方是在web层进行数据绑定时,但是这适用于所有web框架,包括JSF、Struts等。我认为您考虑的是web绑定,而不是bean创建,对吗?如果您担心绑定到表单的视图模型类是可变的,Spring还允许您使用不可变的视图模型类。您必须编写将表单字段转换为模型对象的代码。您需要为从表单字段填充的每个模型类编写类。这意味着您需要权衡不变性v/s的优势和Spring MVC提供的具有可变对象的自动表单绑定的优势。@M.Deinum是的,我说的是web层端的数据绑定,但也包括模型/持久性端的数据绑定。@davioooh模型持久性端不是由Spring处理的,因此,前线的投诉应该针对当前的情况。当涉及到web绑定时,是的,开箱即用不支持不变性,但是您可以为需要的情况编写自己的代码。这不是真的,因为依赖项可以作为构造函数参数注入,从而保持所有Spring托管bean不变。Setter(基于属性的)注入(使对象可变)在存在需要循环依赖关系的合法场景时变得非常有用(
A
依赖于
B
,后者反过来又依赖于
A
).使用@Autowired?@manish这样的注释怎么样?我不认为循环依赖是一种合法的场景,而是一种设计味道……同意,但在一些有效的场景中,循环依赖是必需的。循环依赖在我的书中是不可能的,通常是一个糟糕的设计问题(或古老的库).Spring并没有真正的偏好,除了这样一个事实,特别是最近,通过构造函数参数注入所需的依赖项,而不是将其作为选项(稍后检查
InitializingBean
AfterPropertieSet
方法),Spring集成,新的Spring引导使用基于构造函数的注入或类似的东西,并使用
final
字段。考虑到当今的JVM内存模型和对大规模并发的推动,我想说,一般来说,与6年前几乎没有实现的情况相比,大多数Java程序员正在朝着不可变的方向发展。但据我所见,这仅适用于必需的依赖项或没有默认值的依赖项。但这在今天可能更为明显,尤其是在使用配置类时。