使用Spring提供的BeanUtils.copyProperties将属性复制到Builder

时间:2017-06-20 10:04:20

标签: java spring apache-commons builder lombok

我试图将POJO对象的属性复制到另一个不可变对象的 Builder ,如下所示:

public class CopyTest {

    // the source object
    public static class Pojo1 {
        private int value;

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }
    }

    // the target object
    public static class Pojo2 {
        private final int value;

        public Pojo2(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public static Pojo2Builder builder() {
            return new Pojo2Builder();
        }

        // builder of the target object, maybe generated by lombok
        public static class Pojo2Builder {
            private int value;

            private Pojo2Builder() {}

            public Pojo2Builder value(int value) {
                this.value = value;
                return this;
            }

            public Pojo2 build() {
                return new Pojo2(value);
            }
        }
    }

    public static void main(String[] args) {

        Pojo1 src = new Pojo1();
        src.setValue(1);

        Pojo2.Pojo2Builder builder = Pojo2.builder();

        // this won't work, provided by spring-beans
        BeanUtils.copyProperties(src, builder);

        Pojo2 target = builder.build();
    }

}

问题是:BeanUtils.copyProperties()提供的spring-beans不会致电Pojo2Builder.value(int),因为它不是setter;

除了 Builder 类通常由lombok生成,因此我无法将方法Pojo2Builder.value(int)命名为Pojo2Builder.setValue(int)

顺便说一句,我已经使用apache commons提供的BeanUtilsBean.copyProperties()中的commons-beanutils通过注册自定义BeanIntrospector来使用commons-beanutils,但我发现使用{{1}复制属性当复制发生在两个不同的类之间时,比使用spring-beans要昂贵得多,所以我更喜欢使用spring-beans

是否可以使用Spring或其他一些比commons-beanutils更高效的实用程序将属性复制到 Builder 类?

2 个答案:

答案 0 :(得分:1)

如果构建器不遵循bean约定,那么它将不适用于bean实用程序。

更改构建器,或编写自己的复制实用程序。

答案 1 :(得分:1)

您不仅需要更改方法名称,还需要将其返回类型更改为void(对于构建器而言非常愚蠢)。添加@Setter注释会有所帮助,if it was allowed

如果您需要将值复制到同一个类的构建器中,那么您可以使用Lombok的toBuilder()。或者使用@Wither直接创建对象。

如果你需要坚持使用bean惯例,那么你可能会运气不好。考虑使用mapstruct,这应该更灵活。