在 Lombok 的构建器中使用自定义 setter

新手上路,请多包涵

我在基于 Lombok 的 POJO 中有一个自定义设置器:

 @Data
@Builder
public class User {
    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    private String password = null;

    public void setPassword(String password) {
        Assert.notNull(password);
        this.password = ENCODER.encode(password);
    }

但是当我使用 Lombok 生成的构建器时:

 User user = User.builder()
    .password(password)
    .build();

我的自定义 setter 未被调用,因此密码未被编码。这让我很难过。

当我直接使用它时,当然会调用我的自定义设置器:

 public void changePassword(String password, User user) {
    user.setPassword(password);
}

我该怎么做才能让 Lombok 的构建器使用我的自定义二传手?

原文由 Jan Nielsen 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

根据 @Builder 的文档:只需自己定义足够的骨架。特别是,Lombok 将生成一个类 UserBuilder 、镜像 User 字段的字段和构建器方法,您可以自己提供任何或所有这些。

 @Builder
public class User {
    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    private String username;

    private String password;

    public static class UserBuilder {
        public UserBuilder password(String password) {
            this.password = ENCODER.encode(password);
            return this;
        }
    }
}

原文由 chrylis -cautiouslyoptimistic- 发布,翻译遵循 CC BY-SA 3.0 许可协议

我已经接受了 chrylis 的回答,但为了完整起见,这里有一些方法可以最大限度地减少定制和重复。

带有静态助手的自定义设置器和生成器

静态助手可用于跨自定义 User.UserBuilder::password 方法和自定义 User::setPassword 方法共享大部分 设置密码 功能:

 @Data
@Builder
public class User {
    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    private String password = null;

    public void setPassword(String password) {
        this.password = _encodePassword(password);
    }

    public static class UserBuilder {
        public UserBuilder password(String password) {
            this.password = _encodePassword(password)
            return this;
        }
    }

    private static String _encodePassword(String password) {
        Assert.notNull(password);
        return ENCODER.encode(password);
    }
}

自定义设置器和构造器

自定义构造函数可以使用 User::setPassword 由生成的 Lombok 调用 User.UserBuilder::build()

 @Data
@Builder
public class User {
    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    private String password = null;

    User(String password) {
        setPassword(password);
    }

    public void setPassword(String password) {
        Assert.notNull(password);
        this.password = ENCODER.encode(password);
    }
}

带有静态帮助器的自定义设置器和构造器

或者,更优雅一点,使用自定义构造函数和静态辅助方法:

 @Data
@Builder
public class User {
    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    private String password = null;

    User(String password) {
        _encodePassword(password, this);
    }

    public void setPassword(String password) {
        _encodePassword(password, this);
    }

    private static _encodePassword(String password, User user) {
        Assert.notNull(password);
        user.password = ENCODER.encode(password);
    }
}

原文由 Jan Nielsen 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题