Spring 抽象 class 带有 final 字段并继承了 lombok 的 @SuperBuilder
Spring abstract class with final fields and inheritance with lombok's @SuperBuilder
我目前正在尝试使用 lombok 删除一些样板代码,但遇到了一些麻烦。
我有一个抽象class AbstractParent,
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode
@ToString
@Getter
@Setter
public abstract class AbstractParent {
private final field1;
private final field2;
那我有一个ChildClass这样的
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public abstract class Child extends AbstractParent {
而且我还有一些 classes 扩展 Child class
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Component
public abstract class ExtendedChild extends Child {
private final field1;
private final field2;
由于 lombok 不能在构造函数中使用 super,我尝试了 @SuperBuilder 注解而不是手动定义构造函数,但无法启动应用程序。我完全错过了什么吗?这甚至可以用 lombok 和 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.
我能够用这段代码重现你的问题
@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
在 class ExtendedChild
上的作用是
protected ExtendedChild(ExtendedChildBuilder<?, ?> b) {
super(b);
this.field1 = b.field1;
this.field2 = b.field2;
}
所以它说你需要一个 ExtendedChildBuilder
实例来构建一个 ExtendedChild
实例。换句话说,您必须在 spring 上下文中有一个构建器才能创建您的对象。
这不是一个好主意,因为构建器是有状态的而不是线程安全的。此外,构建器模式在这里能够在构造对象之前随时提供值。使用构建器作为 Spring bean 否定了这种优势。
如果这是您想要实现的不变性,那么使用具有正确参数的普通旧构造函数会更好(如果正确完成,这不是样板代码,这是一个很好的设计)。
那么,Spring注射就是小儿科了
请不要为了编写更少的代码而牺牲复杂性:)
我目前正在尝试使用 lombok 删除一些样板代码,但遇到了一些麻烦。
我有一个抽象class AbstractParent,
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode
@ToString
@Getter
@Setter
public abstract class AbstractParent {
private final field1;
private final field2;
那我有一个ChildClass这样的
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public abstract class Child extends AbstractParent {
而且我还有一些 classes 扩展 Child class
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Component
public abstract class ExtendedChild extends Child {
private final field1;
private final field2;
由于 lombok 不能在构造函数中使用 super,我尝试了 @SuperBuilder 注解而不是手动定义构造函数,但无法启动应用程序。我完全错过了什么吗?这甚至可以用 lombok 和 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.
我能够用这段代码重现你的问题
@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
在 class ExtendedChild
上的作用是
protected ExtendedChild(ExtendedChildBuilder<?, ?> b) {
super(b);
this.field1 = b.field1;
this.field2 = b.field2;
}
所以它说你需要一个 ExtendedChildBuilder
实例来构建一个 ExtendedChild
实例。换句话说,您必须在 spring 上下文中有一个构建器才能创建您的对象。
这不是一个好主意,因为构建器是有状态的而不是线程安全的。此外,构建器模式在这里能够在构造对象之前随时提供值。使用构建器作为 Spring bean 否定了这种优势。
如果这是您想要实现的不变性,那么使用具有正确参数的普通旧构造函数会更好(如果正确完成,这不是样板代码,这是一个很好的设计)。 那么,Spring注射就是小儿科了
请不要为了编写更少的代码而牺牲复杂性:)