前言
有这样的一个需求,前端传的实体类型相同,后端需要根据实体类中的某一个字符串,动态地调用某一个类的方法。
在SpringBoot中,可以理解成,一个Controller接口对应多个ServiceImpl,使用这种方式,如果后期需要添加一个功能,仅仅创建一个ServiceImpl就可以满足需求,而不用再额外创建一个Controller接口。
代码演示
现在假设一个情景,前端传入不同的用户类型,后端返回该用户的任务。
定义一个接口
1
2
3
4
|
public interface UserService {
//返回用户的主要任务
String task();
}
|
两个实现类
1
2
3
4
5
6
7
|
@Service("student")
public class StudentServiceImpl implements UserService {
@Override
public String task() {
return "学习";
}
}
|
1
2
3
4
5
6
7
|
@Service("teacher")
public class TeacherServiceImpl implements UserService {
@Override
public String task() {
return "教书";
}
}
|
实现动态调用的核心类
1
2
3
4
5
6
7
8
9
|
@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对象
实体类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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层接口
1
2
3
4
5
6
7
8
9
10
11
12
|
@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();
}
}
|
测试样例
type为学生时:
type为老师时:
总结
可能用到的场景举例:
关于库存的仪表盘统计:
前端传入区域id,仓库id,物品id等信息
后端依据参数动态地选择某一个物品实现类,最后返回统计的信息
本文所有代码都放在了github上,clone下来即可运行查看效果!