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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42379899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:06:18  来源:igfitidea点击:

Use custom setter in Lombok's builder

javalombok

提问by Jan Nielsen

I have a custom setter in my Lombok-based POJO:

我的基于 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);
    }

but when I use the Lombok generated builder:

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

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

my custom setter is not invoked, and so the password is not encoded. This makes me sad.

我的自定义设置器没有被调用,所以密码没有被编码。这让我很难过。

My custom setter is, of course, invoked when I use it directly:

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

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

What can I do to have Lombok's builder use my custom setter?

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

采纳答案by chrylis -cautiouslyoptimistic-

Per the documentation for @Builder: Just define enough skeleton yourself. In particular, Lombok will generate a class UserBuilder, fields mirroring the Userfields, and builder methods, and you can provide any or all of this yourself.

根据以下文档@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;
        }
    }
}

回答by Bojan Petkovic

You are using setPassword rather than the builder's set method.

您正在使用 setPassword 而不是构建器的 set 方法。

Here is what worked for me:

这是对我有用的:

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());

    }
}

The result was: User(username=This is my username, password=ENCRIYP Password)

结果是: User(username=This is my username, password=ENCRIYP Password)

回答by Jan Nielsen

I've accepted chrylis's answer but for completeness, here's are some ways to minimize customization and duplication.

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

Custom setter and builder with static helper

带有静态助手的自定义 setter 和 builder

A static helper can be used to shares most of the set passwordfunctionality across the custom User.UserBuilder::passwordmethod and the custom User::setPasswordmethod:

静态助手可用于跨自定义方法和自定义方法共享大部分设置密码功能:User.UserBuilder::passwordUser::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);
    }
}

Custom setter and constructor

自定义 setter 和构造函数

A custom constructor can use User::setPasswordwhich is invoked by the Lombok generated User.UserBuilder::build():

可以使用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);
    }
}

Custom setter and constructor with static helper

带有静态助手的自定义 setter 和构造函数

Or, a little more elegantly, with a custom constructor and a static helper method:

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

@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);
    }
}