Use custom setter in Lombok's builder

喜欢而已 提交于 2020-03-13 07:01:07

问题


I have a custom setter in my Lombok-based 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:

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:

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

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


回答1:


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

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



回答2:


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

Custom setter and builder with static helper

A static helper can be used to shares most of the set password functionality across the custom User.UserBuilder::password method and the custom User::setPassword method:

@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

A custom constructor can use User::setPassword which is invoked by the Lombok generated 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

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



回答3:


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

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)



来源:https://stackoverflow.com/questions/42379899/use-custom-setter-in-lomboks-builder

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!