我们假设我有这段代码:
@Controller
@RequestMapping("/something")
public class SomeController {
@Autowired
private SomeService aService;
@RequestMapping("/doStuff")
public void doStuff(@RequestParam("type") String type) {
aService.doStuff();
}
}
在我的应用程序中,我需要根据指定的类型调用特定服务。所有服务都实现相同的接口。如果我理解正确SomeService不能是一个接口。我可以使用服务工厂并在每次新请求完成时根据类型实例化服务,但这看起来效率不高。
或者,我可以为每种不同类型的服务使用不同的控制器(并在REST URI中对类型进行编码),但这意味着大量的代码重复,因为所有服务基本上都实现了相同的接口。
我的问题是,假设被调用的服务依赖于传递的参数,这种情况采用的最佳模式是什么?
答案 0 :(得分:3)
与RC。的答案类似,不是使用Map
并添加值,而是让Spring BeanFactory
为您处理:
@Controller
@RequestMapping("/something")
public class SomeController {
@Autowired
private BeanFactory beanFactory;
@RequestMapping("/doStuff")
public void login(@RequestParam("type") String type) {
SomeService aService = (SomeService)beanFactory.getBean(type);
aService.doStuff();
}
}
答案 1 :(得分:1)
你可以在这里使用地图,其中包括:
@Controller
@RequestMapping("/something")
public class SomeController {
@Autowired
private SomeService someService;
@Autowired
private SomeOtherService someOtherService;
// ...
private final Map<String, ServiceCommonInterface> serviceMap = new HashMap<>();
@PostConstruct
private void postConstruct() {
serviceMap.put(typeForSomeService, someService);
serviceMap.put(typeForSomeOtherService, someOtherService);
}
@RequestMapping("/doStuff")
public void login(@RequestParam("type") String type) {
// TODO: ensure type is correct (an enum might be handy here)
serviceMap.get(type).doStuff();
}
}
或者更好,正如评论中所述,您可以利用限定词:
@Controller
@RequestMapping("/something")
public class SomeController {
@Autowired
private ApplicationContext applicationContext;
@RequestMapping("/doStuff")
public void login(@RequestParam("type") String type) {
// TODO: ensure type is a correct bean name
applicationContext.getBean(type, ServiceCommonInterface.class).doStuff();
}
}
答案 2 :(得分:0)
根据您希望支持的类型数量,我看到了两个选项。
1)如您所述,在工厂中自动装配,并根据需要懒洋洋地创建每项服务。如果服务是无状态的,您可以在创建后保留对该对象的引用,因此每个类型只需要创建一次。
2)在Spring Map中自动装配,其中键是您的类型,值是正确的服务。然后,当您收到类型时,可以为您的地图检索正确的服务impl。
例如,对于地图:http://www.mkyong.com/spring/spring-collections-list-set-map-and-properties-example/或参见How to inject a Map<String, List> in java springs?
这两个都要求您为您的服务创建一个您认为可能的界面。