我已经决定将我的服务从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
)。即使这两个类中有更多的字段,代码看起来也很紧凑。但我们仍然没有constructor-injection
在BaseService
。
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
中实现受保护的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
(当然,可能有多个字段)。
所有的解决方案都有自己的优缺点,但也许有更好的解决方案?
发布于 2021-09-09 08:27:25
最后,与其说这是一个技术性问题,不如说是一个意见问题。这些很棒的工具(如: Lombok,Spring等)使编码变得更容易,所以当我们有疑问时,我们应该回到基础上来。考虑从抽象类继承类的情况,而您没有这些工具。显然,初始化它的正确(也是唯一可能的)方法(如果您想保持代码不耦合)是在继承的类中使用构造函数参数(也非常类似于您的第二个选项)。
如果看起来很难看,而且似乎有很多这样的设计,那只意味着设计不够理想,也许在这一领域内,而不是在技术领域内存在一个问题。也许这个班应该分成几个?在这种情况下使用抽象类比使用接口/具体类更好吗?显然,我不知道您的代码必须解决的挑战,但值得考虑的是设计。
https://stackoverflow.com/questions/69110016
复制相似问题