berg369
2020-02-01 21:40
采纳率: 80%
浏览 2.1k
已采纳

Springboot多个实现类如何根据请求动态切换?

在用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注入不同的实现类,根据不同请求使用特定的(在哪里判断和选择呢?),但不知如何实现;第二种方法可以实现,但是接口在每个方法中都要声明一遍,感觉不太好。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • threenewbee 2020-02-01 23:40
    已采纳

    这个取决于你是希望运行时注入还是通过配置文件切换的方式注入,如果是前者,那么规则是什么,如果是根据业务来判断的,可以用策略设计模式,如果是应用程序全局的,可以使用过滤器拦截器 https://blog.csdn.net/suxinhaixp/article/details/89542561

    打赏 评论

相关推荐 更多相似问题