我在基于Lombok的POJO中有一个自定义setter:
u.LastName LIKE 'B%'
但是当我使用Lombok生成的构建器时:
@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);
}
我的自定义setter未被调用,因此密码未被编码。这让我很伤心。
我的自定义setter当然是在我直接使用时调用的:
User user = User.builder()
.password(password)
.build();
如果让Lombok的构建器使用我的自定义setter,我该怎么办?
答案 0 :(得分:42)
每the documentation for @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;
}
}
}
答案 1 :(得分:2)
您正在使用setPassword而不是构建器的set方法。
这对我有用:
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class User {
private String username;
private String password;
public static class UserBuilder {
private String password;
public UserBuilder password(String password ) {
this.password ="ENCRIYP " + password;
return this;
}
}
public static void main(String[] args) {
System.out.println(User.builder().username("This is my username").password("Password").build().toString());
}
}
结果是:
User(username=This is my username, password=ENCRIYP Password)
答案 2 :(得分:2)
并不是真正的问题答案,而是一个边缘案例,使我花了很多时间来查找问题。
如果在具有Builder
值的字段上具有Builder.Default
且具有自定义设置器,则生成的构建器类中的字段名称与原始字段不同。实际上,您将有两个字段而不是一个:password$value
和password$set
。
不过,您可以通过以下方式在自定义设置器中使用它们:
public UserBuilder password(String password) {
this.password$value = ENCODER.encode(password);
this.password$set = true;
return this;
}
棘手的部分是,如果您使用origianl字段名,则Intellij IDEA不会对此发出警告(好像一切都很好,但是当然不会编译)。已经向插件提交了错误报告。
答案 3 :(得分:0)
我在工作中遇到过这种情况。下面是我想出来的。这个想法是覆盖 Lombok 的 protected User(User.UserBuilder b)
方法
@Data
@Builder
public class User {
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
private String password;
private Integer otherField;
protected User(final User.UserBuilder<?, ?> b) {
setPassword(b.password);
otherField = b.otherField;
}
public void setPassword(String password) {
Assert.notNull(password);
this.password = ENCODER.encode(password);
}
}