【问题标题】:Using SuperBuilder to extend parent class using Lombok使用 SuperBuilder 使用 Lombok 扩展父类
【发布时间】:2021-03-02 08:06:34
【问题描述】:

我有一个使用 Lombok 功能的 DTO,如下所示。但现在由于某些要求,我不得不将我的 DTO 扩展到一个父类,如下所示。我怎样才能在我的 DTO 中做最小的更改来支持它。我尝试使用 @SuperBuilder 注释,但失败了。

DTO 之前:

@Getter
@ToString
@EqualsAndHashCode
@Builder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage {
private final String name;
 }

需要扩展的父类

   @Data
   @SuperBuilder(toBuilder = true)
   @JsonDeserialize(builder = MyDTO.Builder.class)
   public abstract class MyDTO implements Serializable {
   @JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
   protected String myAccountId;

   protected MyDTO() {}

   public static int hashCode(Object... objects) {
     return Arrays.deepHashCode(objects);
   }

   public static boolean equal(Object o1, Object o2) {
    // implementation of equals method
   }

   public abstract String emitSerializedPayload() throws JsonProcessingException;

   @JsonPOJOBuilder(withPrefix = "")
   protected abstract static class Builder<T extends MyDTO, B extends Builder<T, B>> {
   protected T dtoInstance;
   protected B builderInstance;

   public Builder() {
  dtoInstance = createDtoInstance();
  builderInstance = returnBuilderInstance();
}

protected abstract T createDtoInstance();

protected abstract B returnBuilderInstance();

public B myAccountId(String accountId) {
  dtoInstance.myAccountId = accountId;
  return builderInstance;
}

public T build() {
  return dtoInstance;
}
}
}

我尝试手动构建 RequestMessageClass 并且它工作正常,但是我的应用程序中有很多类,我不想手动更改它们,如何使用注释或一些最小更改来更改我现有的 RequestMessage 类以使其正常工作。

这是我尝试过的,但在执行此操作时出现编译错误

    RequestMessage.Builder().name(myName).myAccountId(myAcId).build();
     
     

我尝试的如下所示:

 @Getter
 @ToString
 @EqualsAndHashCode(callSuper = true)
 @SuperBuilder(toBuilder = true)
 @AllArgsConstructor(access = AccessLevel.PRIVATE)
 public class RequestMessage extends MyDTO {
 private final String name;

 @Override
 public String emitSerializedPayload() throws JsonProcessingException {
// TODO Auto-generated method stub
return null;
}
} 
 

【问题讨论】:

  • 您也应该尝试将@Builder@SuperBuilder 注释添加到您的父类中
  • 我做到了@SuperBuilder(toBuilder = true) 但它不起作用,我更新了父类。
  • 您不应该将 lombok @Builder 与静态内部类 Builder 混合使用。在您的情况下,最简单的方法是重构父类并将 Builder 类替换为 @SuperBuilder(toBuilder = true) 注释。
  • 关于删除静态内部类并替换为您所说的超级构建器注释。它给出了错误,说 RequestMessage.Builder 无法解析为类型。在这行代码 RequestMessage.Builder().name(myName).myAccountId(myAcId).build(); 中以 RequestMessage 类型创建类 Builder;
  • 你应该使用.builder() 而不是.Builder()

标签: java spring-boot java-8 lombok dto


【解决方案1】:

您不应该将 lombok @Builder 与静态内部 Builder 类混合使用。如果可以摆脱Builder 类,那么下一个代码应该可以工作。

请求消息

@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
    private final String name;

    @Override
    public String emitSerializedPayload() throws JsonProcessingException {
    return null;
    }
    public RequestMessage(String myAccountId, String name) {
        super(myAccountId);
        this.name = name;
}
}

MyDTO

@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
    @JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
    protected String myAccountId;

    protected MyDTO() {}

    public MyDTO(String myAccountId) {
       this.myAccountId = myAccountId;
    }

    public static int hashCode(Object... objects) {
        return Arrays.deepHashCode(objects);
    }

    public static boolean equal(Object o1, Object o2) {
        // implementation of equals method
        return false;
    }
    public abstract String emitSerializedPayload() throws JsonProcessingException;
}

测试

@Test
void name() {
    String myName = "myName";
    String myAccountId = "myAccountId";
    var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
    System.out.println("request = " + request);
    RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
    

【讨论】:

  • 好的,我试图用 new 实例化它,即 new RequestMessage.builder().name(myName).myAccountId(myAccountId).build()
  • 我不能用新的吗??
  • EqualsAndHashCode(callSuper = true) 和 EqualsAndHashCode 之间应该有什么区别。之前我只是使用 EqualsAndHashCode。 Soo 我可以继续使用相同的方法还是应该调用 Super=true。
  • new 关键字与 Builder 模式无关。如果你想使用它,你需要在父类中声明一个构造函数,然后在子构造函数中使用它(调用(super())。
  • 根据文档:lombok.equalsAndHashCode.callSuper = [call |跳过 | warn](默认值:warn)如果设置为调用,lombok 将生成对 hashCode 的超类实现的调用,如果你的类扩展了某些东西,则等于。如果设置为跳过,则不会生成此类调用。默认行为类似于跳过,带有附加警告。
猜你喜欢
  • 2020-08-25
  • 2020-08-22
  • 2019-06-09
  • 2020-07-18
  • 2021-06-08
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2014-03-12
相关资源
最近更新 更多