简体   繁体   English

Spring 抽象 class 与最终字段和 inheritance 与 lombok 的 @SuperBuilder

[英]Spring abstract class with final fields and inheritance with lombok's @SuperBuilder

I am currently trying to remove some boilerplate code with lombok but have some trouble.我目前正在尝试使用 lombok 删除一些样板代码,但遇到了一些麻烦。

I have an abstract class AbstractParent,我有一个抽象的 class AbstractParent,

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

then I have a Child Class like this然后我有一个像这样的孩子 Class

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

And I also have some classes extending the Child class而且我还有一些类扩展了子 class

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

Since lombok can't use super in a constructor, I tried the @SuperBuilder Annotation instead of defining the Constructors manually but can't get the Application to start.由于 lombok 不能在构造函数中使用 super,我尝试了 @SuperBuilder 注释而不是手动定义构造函数,但无法启动应用程序。 Am I missing something completely?我完全错过了什么吗? Is this even possible with lombok and spring?龙目岛和 spring 甚至可能吗?

The Error is:错误是:

***************************
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.

I was able to reproduce your problem with this code我能够用这段代码重现你的问题

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

What the @SuperBuilder does here on class ExtendedChild is @SuperBuilder在 class ExtendedChild上的作用是

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

So it says you need an ExtendedChildBuilder instance in order to build an ExtendedChild instance.所以它说你需要一个ExtendedChildBuilder实例才能构建一个ExtendedChild实例。 In order words, you have to have a builder in your spring context to be able to create your object.换句话说,您必须在 spring 上下文中有一个构建器才能创建 object。

This is not a good idea since a builder is stateful and not thread-safe.这不是一个好主意,因为构建器是有状态的并且不是线程安全的。 Furthermore, the builder pattern is here to be able to provide values whenever you need them before constructing your object.此外,在构建 object 之前,构建器模式可以在您需要时提供值。 Using a builder as a Spring bean denies that advantage.使用构建器作为 Spring bean 否认了这种优势。

If this is immutability you want to achieve, then using plain old constructors with the right parameters is way better (and when done right, this is not boilerplate code, this is good design).如果这是您想要实现的不变性,那么使用具有正确参数的普通旧构造函数会更好(如果做得正确,这不是样板代码,这是很好的设计)。 Then, Spring injection will be a child's play.那么,Spring 注入将是小菜一碟。

Please do not trade complexity for the sake of writing less code:)请不要为了编写更少的代码而牺牲复杂性:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM