【发布时间】:2021-11-05 15:18:09
【问题描述】:
我已决定将我的服务从 Spring setter-injection 更新为 constructor-injection 以逐步摆脱循环依赖关系。问题是服务使用继承,并且父服务和子服务都有自己的字段。所以问题是 - 使用Lombok 实现构造函数注入的最佳方法是什么。
以下是原始代码示例:
@Setter(onMethod_ = @Autowired)
public abstract class BaseService {
protected FooService fooService;
}
@Service
@Setter(onMethod_ = @Autowired)
public class ConcreteService extends BaseService {
private BarService barService;
}
FooService 用于BaseService 和ConcreteService。
以下是可能的解决方案:
1. 在ConcreteService 中实现constructor-injection。
@Setter(onMethod_ = @Autowired)
public abstract class BaseService {
protected FooService fooService;
}
@Service
@RequiredArgsConstructor
public class ConcreteService extends BaseService {
private final barService BarService;
}
我们很好地使用了@RequiredArgsConstructor注解,因为不需要调用super(Lombok不支持调用super)。即使两个类中有更多字段,代码看起来也很紧凑。但是我们在BaseService 中仍然没有constructor-injection。
2. 将受保护的构造函数添加到BaseService 并在ConcreteService 构造函数中调用super。
@RequiredArgsConstructor(AccessLevel.PROTECTED)
public abstract class BaseService {
protected final FooService fooService;
}
@Service
public class ConcreteService extends BaseService {
private final BarService barService;
public ConcreteService(FooService fooService, BarService barService) {
super(fooService);
this.barService = barService;
}
}
实现的主要目标 - constructor-injection 已实现,BaseService 看起来不错,但 ConcreteService 有一个丑陋的构造函数,其中应该传递两个服务的所有参数(并且可能是大量参数)。让我们再试一次。
3.将所有字段移至ConcreteService,在BaseService中实现protected getter以访问FooService。
public abstract class BaseService {
protected abstract FooService getFooService();
}
@Service
@RequiredArgsConstructor
public class ConcreteService extends BaseService {
private final FooService fooService;
private final BarService barService;
}
主要目标也实现了 - 我们有一个constructor-injection,构造函数看起来很干净,但现在我们应该在所有BaseService 继承者中都有一个FooService(当然可以有多个字段)。
所有解决方案都各有利弊,但也许有更好的解决方案?
【问题讨论】:
标签: java spring inheritance dependency-injection lombok