java - 避免 Spring Boot 中的长依赖列表
问题描述
我正在编写具有越来越多的接口实现的代码VendorService
。现在,在使用这些服务的地方,我们在构造函数中将它们全部自动装配,从而导致一长串依赖项。当重复使用单个接口时,是否有首选方法来处理依赖关系?
目前的做法:
private final VendorService xVendorService;
private final VendorService yVendorService;
private final VendorService zVendorService;
...
@Autowired
public VendorDelegateService(XVendorService xVendorService,
YVendorService yVendorService,
ZVendorService zVendorService,
...) {
this.xVendorService = xVendorService;
this.yVendorService = yVendorService;
this.yVendorService = yVendorService;
...
}
public void doSomething(VendorId vendorId) {
if (vendorId = VendorId.X) {
xVendorService.doSomething();
} else if (vendorId = VendorId.Y) {
yVendorService.doSomething();
} else if (vendorId = VendorId.Z) {
zVendorService.doSomething();
}
...
}
显然,这是非常冗长的,并且每当创建接口的新实现时都需要更新。
另一种方法是从 ApplicationContext 获取 Bean,例如:
private final ApplicationContext context;
@Autowired
public VendorDelegateService(ApplicationContext context) {
this.context = context;
}
public void doSomething(VendorId vendorId) {
context.getBean(VendorService.class, vendorId.name()).doSomething();
}
这不需要每个新实现都使用另一个 if/else 括号,但它很钝并且感觉不正确。这个逻辑当然可以在它自己的类中抽象出来以减轻这个问题。
这些在 Spring 和 Java 中哪个更惯用?还有其他我没有考虑过的方法吗?
解决方案
我觉得是否有一种惯用的方式是一个偏好问题,但我建议的是以下解决方案:
为所有服务创建一个接口,我们可以称之为VendorService
:
public interface VendorService {
void doSomething();
VendorId getVendorId();
}
现在我们希望为所有服务实现这个接口,例如,可以这样完成XVendorService
:
@Service
public XVendorService implements VendorService {
private VendorId vendorId = ....
@Override
public void doSomething() {
...
}
@Override
public VendorId getKey() {
return vendorId;
}
}
现在VendorDelegateService
我们可以这样做:
@Service
public class VendorDelegateService {
private Map<VendorId, VendorService> services = new HashMap<>();
@Autowired
public AllServices(Set<? extends VendorService> serviceSet) {
serviceSet.stream().forEach(service -> services.put(service.getVendorId(), service));
}
public void doSomething(VendorId vendorId) {
if (services.containsKey(vendorId)) {
services.get(vendorId).doSomething();
}
}
}
请注意,Set<? extends VendorService> serviceSet
所有服务都将自动自动连接。通过之后创建一个地图,我们可以将我们的请求发送到基于它的每个服务vendorKey
。
推荐阅读
- python-3.x - Python3 networkx plane_layout 节点位置和图形大小
- python - python pandas:如何为折线图切换x轴和y轴
- flutter - 如何根据 Flutter 中另一个文本字段的值自动设置文本字段的值?
- amazon-web-services - 尝试从 VPC 内的 S3 将数据读入 AWS SageMaker 时出错
- javascript - 反应巨大的数组排序(5k项)
- javascript - iOS 15 WebShare 支持的文件类型
- cmake - 尽管没有更改源,CMake 仍会重建自定义目标
- python - 在 StellarGraph 中使用 Hinsage/Graphsage 的链接预测返回 NaN
- python - python检查字符串上的字谜
- python - Python读取文件添加额外字符