当前位置 博文首页 > 阳阳的博客:【SpringBoot】使用不同的策略动态地调用某个接口的

    阳阳的博客:【SpringBoot】使用不同的策略动态地调用某个接口的

    作者:[db:作者] 时间:2021-08-14 21:04

    1、前言

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

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


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

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

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


    2、代码演示

    我们先定义一个接口

    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 "教书";
        }
    }

    实现动态调用的核心类

    @Service
    public 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();
        }
    }

    测试样例:


    3、可能用到的场景举例

    关于库存的仪表盘统计

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

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

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

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

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

    cs
    下一篇:没有了