文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

springboot怎么通过不同的策略动态调用不同的实现类

2023-06-29 08:10

关注

这篇“springboot怎么通过不同的策略动态调用不同的实现类”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“springboot怎么通过不同的策略动态调用不同的实现类”文章吧。

通过不同的策略动态调用不同的实现类

经常遇到这样的一个需求,前端传的实体类型相同,后端需要根据实体类中的某一个字符串,动态地调用某一个类的方法。

在SpringBoot中,我们可以理解成,一个Controller接口对应多个ServiceImpl,使用这种方式,如果后期需要添加一个功能,仅仅创建一个ServiceImpl就可以满足需求,而不用再额外创建一个Controller接口。

现在假设一个情景,前端传入不同的用户类型,后端返回该用户的任务。

你可能问我,为什么不直接把(用户类型,用户任务)存入数据库?

现在只是一个简单的场景而已,实际中更为复杂,无法直接存入数据库。

代码演示

我们先定义一个接口

public interface UserService {     //返回用户的主要任务    String task();}

两个实现类

@Service("student")public class StudentServiceImpl implements UserService {    @Override    public String task() {        return "学习";    }}
@Service("teacher")public class TeacherServiceImpl implements UserService {    @Override    public String task() {        return "教书";    }}

实现动态调用的核心类

@Servicepublic class UserContext {     @Autowired    Map<String, UserService> userMap;     public UserService getUserService(String type) {        return userMap.get(type);    }}

Spring会自动地将形如(@Service后面的名称,实现该接口的类)注入到该userMap中

在启动后,userMap中就存在两个元素,("student",StudentServiceImpl)与("teacher",TeacherServiceImpl)

getUserService方法返回userMap中key=type的UserService对象

实体类

public class User {     private String type;     private String task;     public String getType() {        return type;    }     public void setType(String type) {        this.type = type;    }     public String getTask() {        return task;    }     public void setTask(String task) {        this.task = task;    }}

Controller层接口

@RestController@RequestMapping("/user")public class UserController {     @Autowired    UserContext userContext;     @PostMapping("/getTask")    public String getTask(@RequestBody User user) {        UserService userService = userContext.getUserService(user.getType());        return userService.task();    }}

测试样例:

springboot怎么通过不同的策略动态调用不同的实现类

springboot怎么通过不同的策略动态调用不同的实现类

可能用到的场景举例

关于库存的仪表盘统计

前端传入区域id,仓库id,物品id等信息

后端依据参数动态地选择某一个物品实现类,最后返回统计的信息。

这里有几个问题,为什么不一次性将所有物品id传入,一次性获取所有物品的库存?

一次性传入,可能后端处理时间边长,失败率也高,一旦失败,整个仪表盘没有任何数据。而且后期可能面临的一个需求,不同的物品,需要有不同的接口刷新速度,畅销的物品接口调用频率快。所以可能需要将物品分组,一个小组是同一种类型,使用一个实现类。

比如,这里有100种物品,按类型或者其他属性分成了10组,每个组之间,有一个不同的属性groupId,但10组共用一个接口,进入接口后,再进入10个不同的实现类,在实现类中调用具体的计算逻辑。

spring中动态选择实现类

在spring中当一个接口有多个实现类的时候,通过创建简单工厂类,根据传入的不同的参数获取不同的接口实现类。

public interface ExecuteService {        ExecuteEnum getCode();    // 业务方法    void execute();}
@Servicepublic class FirstExecuteServiceImpl implements ExecuteService {        @Override    public ExecuteEnum getCode() {        return ExecuteEnum.FIRST;    }        public void execute() {        System.out.println("11111111111");    }}
@Servicepublic class SecondExecuteServiceImpl implements ExecuteService {        @Override    public ExecuteEnum getCode() {        return ExecuteEnum.SECOND;    }        public void execute() {        System.out.println("222222222");    }}
    public enum ExecuteEnum {        FIRST,        SECOND,;    }

方案一

@Componentpublic class ExecuteServiceFactory implements ApplicationContextAware {        private final static Map<ExecuteEnum, ExecuteService> EXECUTE_SERVICES = new HashMap<>();    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        Map<String, ExecuteService> types = applicationContext.getBeansOfType(ExecuteService.class);        types.values().forEach(e -> EXECUTE_SERVICES.putIfAbsent(e.getCode(), e));    }    }

方案二

@Componentpublic class ExecuteServiceFactory implements InitializingBean {    @Autowired    private List<ExecuteService> executeServices;    public final static Map<ExecuteEnum, ExecuteService> EXECUTE_SERVICES = new HashMap<>();    @Override    public void afterPropertiesSet() throws Exception {        executeServices.forEach(l -> EXECUTE_SERVICES.putIfAbsent(l.getCode(), l));    }}

以上就是关于“springboot怎么通过不同的策略动态调用不同的实现类”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯