在用springboot开发时,由controller、service接口、service实现组成,一个service接口有多种实现类,需要实现根据不同的请求,例如不同地区的请求,调用不同的实现类,这种实现类和地区的对应有一个配置,我们计划加一个filter从请求中取出IP所在区域,并找出对应的实现类,可以放到某个全局变量或线程变量中,但我们怎么实现让Service注入不同的实现类呢?或者说,我们应如何实现这种需求呢?注意我们的所有service都可能有多个实现类,这个实现类与区域的对应配置是另外维护的。
我的理解spring中Bean是单例,完成装配或注入即不变了,怎么能实现根据请求更换实现类呢?如果能实现,在哪里做呢?我想肯定不应在controller代码中做,不应该每个Controller都加这种判断和选择代码,那么这种判断和选择加到哪里呢?能在filter里做吗?根据所选实现类修改bean的绑定吗?但这样会不会在并发情况下有冲突?
代码是Spring常规的,如下controller:
@RestController
public class TestController {
@Autowired
private TestService testService;
@RequestMapping(value = "/api/test", method = RequestMethod.GET)
public User findOne(@RequestParam(value = "name", required = true) String name) {
return testService.findByName(name);
}
}
service接口:
public interface TestService {
User findByName(String name);
}
实现类1:
@Service
@Primary //默认的实现类
public class TestServiceImpl1 implements TestService {
@Autowired
private UserDao userDao;
public User findByName(String name) {
return userDao.findByName(name);
}
实现类2:
@Service
public class TestServiceImpl2 implements TestService {
@Autowired
private UserDao userDao;
public User findByName(String name) {
return userDao.findByName(name+"2");
}
1、有人说用多例模式,多例声明在controller还是service实现类呢(我想应该是controller多例吧,service仍然可以作为单例来用)?实现类的选择在哪里动态实现呢(同样不希望在所有Controller中写)?如果用多例能够实现,spring装配还有意义吗?--我觉得不应该是多例,太浪费资源了,能否按照实现类组合创建多个单例(实际就是多例,但不是一个请求创建一个,而是一种组合创建一个)呢?嗯,我觉得这种思路对,但不知从何下手!spring支持这种根据类组合的多实例装配吗?
2、我想了另一种方案,controller统一这样写:
@RestController
public class TestController {
@RequestMapping(value = "/api/test", method = RequestMethod.GET)
public User findOne(@RequestParam(value = "name", required = true) String name) {
TestService testService=ServiceUtil.getServiceImp();
return testService.findByName(name);
}
}
提供一个工具类ServiceUtil,静态方法getServiceImp()根据线程变量所对应的类名返回对象,但这种方式是否就不那么spring了,而且每个方法中都要声明,这样好吗?
综上,第一种方案我觉得更好,按照spring的规则写代码,如果有多个实现类,就装配多个controller注入不同的实现类,根据不同请求使用特定的(在哪里判断和选择呢?),但不知如何实现;第二种方法可以实现,但是接口在每个方法中都要声明一遍,感觉不太好。