【问题标题】:Copy properties to a Builder with BeanUtils.copyProperties provided by Spring使用 Spring 提供的 BeanUtils.copyProperties 将属性复制到 Builder
【发布时间】:2017-11-22 19:34:45
【问题描述】:

我正在尝试将 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();
    }

}

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

除了 Builder 类通常由lombok 生成,所以我不能将方法Pojo2Builder.value(int) 命名为Pojo2Builder.setValue(int)

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

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

【问题讨论】:

    标签: java spring apache-commons builder lombok


    【解决方案1】:

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

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

    如果您需要坚持 bean 约定,那么您可能不走运。考虑使用mapstruct,应该更灵活。

    【讨论】:

      【解决方案2】:

      如果构建器不遵循 bean 约定,那么它将无法与 bean 实用程序一起使用。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-02
        • 2017-11-28
        • 1970-01-01
        • 1970-01-01
        • 2019-03-30
        • 2021-02-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多