当前位置: 首页 > 知识库问答 >
问题:

Spring抽象类,带有最终字段,并使用lombok的@SuperBuilder继承

严亦
2023-03-14

我目前正试图用lombok删除一些样板代码,但遇到了一些问题。

我有一个抽象类AbstractParent,

@SuperBuilder(toBuilder = true)
@EqualsAndHashCode
@ToString
@Getter
@Setter
public abstract class AbstractParent {
private final field1;
private final field2;

然后我有一个像这样的儿童班

@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public abstract class Child extends AbstractParent {

我还有一些类扩展了Child类

@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Component
public abstract class ExtendedChild extends Child {
private final field1;
private final field2;

由于Lombok不能在构造函数中使用超级,我尝试了@SuperBuilder注释,而不是手动定义构造函数,但无法启动应用程序。我是不是完全错过了什么?龙目岛和Spring有可能吗?

错误是:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.fu.extendedChild required a bean of type 'com.fu.extendedChild$extendedChildBuilder' that could not be found.


Action:

Consider defining a bean of type 'com.fu.extendedChild$extendedChildBuilder' in your configuration.

共有1个答案

周和歌
2023-03-14

我用这个代码重现了你的问题

@SuperBuilder(toBuilder = true)
@EqualsAndHashCode
@ToString
@Getter
@Setter
public abstract class AbstractParent {
    private final String field1;
    private final String field2;
}

@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
abstract class Child extends AbstractParent {

}

@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Component
class ExtendedChild extends Child {
    private final String field1;
    private final String field2;
}

@SuperBuilder在类ExtendedChild上所做的是

protected ExtendedChild(ExtendedChildBuilder<?, ?> b) {
    super(b);
    this.field1 = b.field1;
    this.field2 = b.field2;
}

所以它说你需要一个ExtendedChildBuilder实例来构建一个ExtendedChilder实例。换句话说,你必须在你的Spring上下文中有一个构建器才能创建你的对象。

这不是一个好主意,因为构建器是有状态的,不是线程安全的。此外,构建器模式可以在构建对象之前随时提供需要的值。使用构建器作为Spring bean否认了这一优势。

若这是您想要实现的不变性,那个么使用带有正确参数的普通旧构造函数要好得多(当正确完成时,这不是样板代码,这是一个很好的设计)。那么,Spring注射将是一个孩子的游戏。

请不要为了编写更少的代码而牺牲复杂性:)

 类似资料:
  • 给定以下具有Lombok注释的类和 在中的注释上出现以下错误: 隐式超级构造函数Parent()未定义。必须显式调用另一个构造函数。 我在子类和父类上尝试了、、注释与注释的几种不同组合,但还没有找到一个有效的解决方案。我使用的是Lombok 1.18.10。 供参考,这个问题是相关的 编辑

  • 我有以下课程: 为什么我无法在抽象类(< code>Parent)的实例上调用< code>toBuilder(),如下面的代码所示?

  • 问题内容: 我想知道下面的代码是否有意义,因为编译器会警告“空白的最终字段对象可能尚未初始化”。有更好的方法吗? 问题答案: 我将字段定为final,并强制构造函数将值向上传递:

  • 问题内容: 我有一个很简单的问题: 我想要一个Java类,该类提供一个公共静态方法,该方法可以执行某些操作。这只是出于封装目的(将所有重要的内容都放在一个单独的类中)… 此类不应被实例化或扩展。那让我写道: (尽管我知道,这是禁止的)。 我也知道,我可以使此类完全为final,并在将其私有化时覆盖标准构造函数。 但这在我看来更像是一种“解决方法”,应该更可能由最终的抽象类完成… 而且我讨厌解决方法

  • 我有一个抽象类的许多子类,每个子类都声明了一个同名的公共静态final字段。我在考虑在抽象超类中包含这个字段,而不初始化它,并希望每个子类都能被强制初始化它。 我之所以这么想,是因为抽象类的所有子类都声明了一个名为UNIQUE_ID的公共静态最终字符串字段,并且每个子类都有必要声明一个具有该名称的字段。 我希望我的问题足够清楚,如果不清楚,请告诉我。 能不能做一些和这个差不多的事情? 编辑:添加代

  • 问题内容: 您将如何在以下示例代码中配置注释?我只想保留JPA注释,避免使用Hibernate特定的依赖项。 下面的代码正确吗? (这些类将具有多个版本,RefSomeOtherExample等,并且每个类一个db表。有些可能会添加其他字段(列),但大多数只会使用继承自“ RefData”基类的基本字段。) 基类: 最终,我想使用Hibernate的SchemaExport类从中生成模式创建脚本。