SpringBoot使用不同的策略动态地调用某个接口的实现类

createh53周前 (12-10)技术教程18

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个不同的实现类,在实现类中调用具体的计算逻辑。

相关文章

一文讲透Java序列化

前言 Oracle 公司计划废除 Java 中的古董:序列化技术,因为它带来了许多严重的安全问题(如序列化存储安全、反序列化安全、传输安全等),据统计,至少有3分之1的漏洞是序列化带来的,这也是 19...

Java基础:Object类

Object类概述Object类是Java中所有类的始祖,在Java中每个类都是由它扩展而来的;当一个类没有直接继承某个类时,默认继承Object类,也就是说任何类都直接或间接继承Object类,Ob...

一文弄懂-Java:类的加载过程

0 文由其一,工欲善其事,必先利其器。编程语言是软件开发工作中基础的基础。其二,学习的两重境界,知其然,知其所以然。前者回答了“是什么”,后者回答“为什么”。笔者力求在这两方面“雨露均沾”。其三,因此...

Java程序设计试卷

JAVA程序设计试卷库(第5套)一、单选题(每小题 2 分,共 20 分)1、Java Application源程序的主类是指包含有( A )方法的类。A. main方法 B. toString方法C...