【发布时间】:2018-11-13 04:39:48
【问题描述】:
我正在开发一个 REST API,其中我有一个接口,它定义了由 4 个不同类实现的方法列表,将来可能会添加更多。
当我收到来自客户端的 HTTP 请求时,URL 中包含一些信息,这些信息将确定需要使用哪个实现。
在我的控制器中,我希望端点方法包含一个 switch 语句,该语句检查 URL 路径变量,然后使用适当的实现。
我知道我可以定义具体实现并将其注入控制器,然后在 switch 语句中插入我想在每个特定情况下使用的实现,但这似乎不是很优雅或可扩展,原因有两个:
我现在必须实例化所有服务,即使我只需要使用一个。
1234563实现列表在增长……案例和冗余代码的数量也在增长。
有没有更好的解决方案来解决这种情况?我正在使用 SpringBoot 2 和 JDK 10,理想情况下,我想实现最现代的解决方案。
我目前的方法
@RequestMapping(Requests.MY_BASE_API_URL)
public class MyController {
//== FIELDS ==
private final ConcreteServiceImpl1 concreteService1;
private final ConcreteServiceImpl2 concreteService2;
private final ConcreteServiceImpl3 concreteService3;
//== CONSTRUCTORS ==
@Autowired
public MyController(ConcreteServiceImpl1 concreteService1, ConcreteServiceImpl2 concreteService2,
ConcreteServiceImpl3 concreteService3){
this.concreteService1 = concreteService1;
this.concreteService2 = concreteService2;
this.concreteService3 = concreteService3;
}
//== REQUEST MAPPINGS ==
@GetMapping(Requests.SPECIFIC_REQUEST)
public ResponseEntity<?> handleSpecificRequest(@PathVariable String source,
@RequestParam String start,
@RequestParam String end){
source = source.toLowerCase();
if(MyConstants.SOURCES.contains(source)){
switch(source){
case("value1"):
concreteService1.doSomething(start, end);
break;
case("value2"):
concreteService2.doSomething(start, end);
break;
case("value3"):
concreteService3.doSomething(start, end);
break;
}
}else{
//An invalid source path variable was recieved
}
//Return something after additional processing
return null;
}
}
【问题讨论】:
-
我认为,如果来源可能性很小,您可以为每个来源提供单独的其余映射 api。或者如果有更多来源的可能性,那么检查是否有一种方法可以在服务层本身而不是在 api 级别合并处理多个来源的逻辑。
-
我也想过这一点,实际上我最初是这样设置控制器的,但我遇到了同样的问题,因为我将实现自动装配到构造函数中。在这种特殊情况下,如果我要在同一个控制器中为每个源添加不同的映射,那么我会有更多的样板代码。这种方法的唯一选择是为每个源使用不同的控制器,这是可行的......但它似乎更像是一种解决方法而不是解决方案,但如果我找不到更好的方法,我可能会采用这种方法。跨度>
-
检查您是否可以设计一种服务实现来处理不同来源的条件逻辑,从而通过将源参数传递给serviceImpl,您可以在一个类和一个相应的api中拥有逻辑。
-
将检测委托给服务。注入您的服务列表(接口)。然后在您的方法中遍历您的服务列表,并调用一个方法以查看它们是否可以处理请求/源。当你找到正确的,使用它。这样你就有了一个可扩展的机制。
标签: java spring spring-mvc spring-boot dependency-injection