为了账号安全,请及时绑定邮箱和手机立即绑定

Spring 5 不可变形式在没有参数构造函数时也使用全参数构造函数

Spring 5 不可变形式在没有参数构造函数时也使用全参数构造函数

米琪卡哇伊 2023-05-24 16:12:31
在一个不可变的类/对象中,我有一个没有参数的构造函数将值初始化为默认值/null,另一个必需的参数构造函数将所有值初始化为构造函数的参数。使用表单绑定时(通过在控制器中的请求参数中指定),spring 始终调用无参数构造函数而不初始化值。我怎样才能确保 spring 只调用所需的参数构造函数?这是在 spring 版本 5.1.5 中。我也尝试在“必需的参数构造函数”上添加 @ConstructorProperties,但无济于事。我的不可变表单/bean 对象:public class ImmutableObj {    private final Integer id;    private final String name;    // no arg constructor    // spring calls this one when resolving request params    public ImmutableObj() {        this(null, null);    }    // required args constructor    // I want spring to call this one when resolving request params    @ConstructorProperies({"id", "name"})    public ImmutableObj(Integer id, String name) {        this.id = id;        this.name = name;    }    public Integer getId() {        return id;    }    public String getName() {        return name;    }}还有我的控制器:@Controllerpublic class MyController {    @GetMapping("myStuff")    public String getMyStuff(ImmutableObj requestParams) {        // here the value of request params        // has nulls due to no arg constructor being called         return "someStuff";    }}调用“/myStuff?id=123&name=hello”时预期的 -requestParams.getId()=123, requestParams.getName()=hello实际的 -requestParams.getId()=null, requestParams.getName()=null
查看完整描述

1 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

Spring 总是调用无参数构造函数而不是初始化值。

当 Spring 发现该类有多个构造函数时,它会去寻找一个无参数的构造函数。如果 Spring 没有找到它,它将抛出异常。

当 Spring 发现该类只有一个构造函数时,它会接受它,而不管它有多少个参数。

我怎样才能确保 spring 只调用所需的参数构造函数?

唯一的方法是在类中只有一个构造函数。使它在 Spring 中明确无误。

作为旁注,

  1. @ConstructorProperies({"id", "name"})如果字段名称对应于 URL 参数名称,则不需要。Spring 可以解决这个问题。

  2. public ImmutableObj() { 
       this(null, null);
    }

这不是一个好主意。ImmutableObj.empty()会更好。

作为奖励,如果你想看看幕后发生了什么,这是我正在谈论的片段

if (ctor == null) {

  Constructor<?>[] ctors = clazz.getConstructors();

  if (ctors.length == 1) {

    ctor = ctors[0];

  } else {

    try {

      ctor = clazz.getDeclaredConstructor();

    } catch (NoSuchMethodException var10) {

      throw new IllegalStateException("No primary or default constructor found for " + clazz, var10);

    }

  }

}


查看完整回答
反对 回复 2023-05-24
  • 1 回答
  • 0 关注
  • 106 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信