先理解一行代码
| 12
 
 | @ResourceMap<String, ProductService> ServiceMap = new ConcurrentHashMap<>(2);
 
 | 
此代码在 Spring Boot 启动时会被执行并创建一个 ConcurrentHashMap 实例, 以及它所引用的 ProductService 实现类的实例对象. 这些对象将被记录到map中
其中 String 就是 ProductService类的名字, 可以通过@Service(“serviceA”)来修改. 如果 ProductService 是一个接口. 那么 String 就是其对应的接口的名字.
实践一个简单的
- 编写 Controller 代码时, 经常遇到根据入参不同, 执行不同的 Service 逻辑的需求, 我们最常用的 if 来判断. 代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | @RestController
 public class ProductController {
 @Resource
 private ServiceOrderA serviceOrderA;
 @Resource
 private ServiceOrderB serviceOrderB;
 
 
 
 @PostMapping("/order")
 public String order(@RequestParam(value = "type") String type) {
 if ("productA".equals(type)) {
 return  serviceOrderA.orderingProduct();
 } else if ("productB".equals(type)) {
 return  serviceOrderB.orderingProduct();
 
 
 
 }else {
 return "没有发现对应的产品处理策略";
 }
 }
 
 }
 
 | 
- 当 type 变多时, 需要注入很多的 private ServiceOrderA serviceOrderA; if 判断链也会很长. 代码杂乱没有章法, 且显得没有技术含量. 🙃
- 此时引入策略模式, 所有 Service 抽象成 ProductService
| 12
 3
 
 | public interface ProductService {String orderingProduct();
 }
 
 | 
- 不同 Service 实现不同的 orderingProduct 逻辑
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 |     @Service("productA")public class ProductAServiceImpl implements ProductService {
 @Override
 public String orderingProduct() {
 return "成功订购产品A";
 }
 }
 
 @Service("productB")
 public class ProductBServiceImpl implements ProductService {
 @Override
 public String orderingProduct() {
 return "成功订购产品B";
 }
 }
 
 | 
- 增加容器存放 Service 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 
 | @Componentpublic class InterfaceContainer {
 
 @Resource
 Map<String, ProductService> configComponentMap = new ConcurrentHashMap<>(2);
 
 public ProductService getProductStrategy(String productName) {
 
 return configComponentMap.get(productName);
 }
 
 }
 
 
 | 
- 简化 Controller
| 12
 3
 4
 5
 6
 7
 
 | @Resourceprivate InterfaceContainer interfaceContainer;
 @PostMapping("/order1")
 public String order1(@RequestParam(value = "type") String type) {
 ProductService productService = interfaceContainer.getProductStrategy(type);
 return productService != null ? productService.orderingProduct() : "没有发现对应的产品处理策略";
 }
 
 | 
再来一个实际运用
设计一个前后端分离系统, 会涉及到很多单表的通用操作, 比如都根据id查询明细, 都通过自定义参数查询, 查询表的总行数用于分页, 单表写入, 单表更新等接口. 
每个单表服务都写一个 controller ? 可以但不够优雅. 
我们依旧采用策略模式优化. 
此类通用操作先抽象成接口 ICommonQuery. 增加一个管理类来处理接口调用逻辑 CommonQueryManager
每个服务分别实现接口, 完成自己的逻辑.
外部暴露一个 controller. 通过 @PathVariable 获取 url 的 apiname, 然后去 map 中获取 Service. 进而调用到对应的服务.
ICommonQuery
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 
 | public interface ICommonQuery {
 
 
 
 
 
 Object selectOne(Long id) throws Exception;
 
 
 
 
 
 
 
 List<?> select(Map<String, String> parameterMap) throws Exception;
 
 
 
 
 
 
 
 Long counts(Map<String, String> parameterMap) throws Exception;
 
 
 
 
 
 
 
 int insert(JSONObject obj, HttpServletRequest request) throws Exception;
 
 
 
 
 
 
 
 int update(JSONObject obj, HttpServletRequest request) throws Exception;
 
 
 
 
 
 
 
 int delete(Long id, HttpServletRequest request) throws Exception;
 
 
 
 
 
 
 
 int deleteBatch(String ids, HttpServletRequest request) throws Exception;
 
 
 
 
 
 
 
 int checkIsNameExist(Long id, String name) throws Exception;
 }
 
 | 
CommonQueryManager
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 
 | @Service
 public class CommonQueryManager {
 
 @Resource
 private InterfaceContainer container;
 
 
 
 
 
 
 
 public Object selectOne(String apiName, Long id) throws Exception {
 if (StringUtils.isNotEmpty(apiName) && id!=null) {
 return container.getCommonQuery(apiName).selectOne(id);
 }
 return null;
 }
 
 
 
 
 
 
 
 public List<?> select(String apiName, Map<String, String> parameterMap)throws Exception {
 if (StringUtils.isNotEmpty(apiName)) {
 return container.getCommonQuery(apiName).select(parameterMap);
 }
 return new ArrayList<Object>();
 }
 
 
 
 
 
 
 
 public Long counts(String apiName, Map<String, String> parameterMap)throws Exception {
 if (StringUtils.isNotEmpty(apiName)) {
 return container.getCommonQuery(apiName).counts(parameterMap);
 }
 return 0L;
 }
 
 
 
 
 
 
 
 @Transactional(value = "transactionManager", rollbackFor = Exception.class)
 public int insert(String apiName, JSONObject obj, HttpServletRequest request) throws Exception{
 if (StringUtils.isNotEmpty(apiName)) {
 return container.getCommonQuery(apiName).insert(obj, request);
 }
 return 0;
 }
 
 
 
 
 
 
 
 @Transactional(value = "transactionManager", rollbackFor = Exception.class)
 public int update(String apiName, JSONObject obj, HttpServletRequest request)throws Exception {
 if (StringUtils.isNotEmpty(apiName)) {
 return container.getCommonQuery(apiName).update(obj, request);
 }
 return 0;
 }
 
 
 
 
 
 
 
 @Transactional(value = "transactionManager", rollbackFor = Exception.class)
 public int delete(String apiName, Long id, HttpServletRequest request)throws Exception {
 if (StringUtils.isNotEmpty(apiName)) {
 return container.getCommonQuery(apiName).delete(id, request);
 }
 return 0;
 }
 
 
 
 
 
 
 
 @Transactional(value = "transactionManager", rollbackFor = Exception.class)
 public int deleteBatch(String apiName, String ids, HttpServletRequest request)throws Exception {
 if (StringUtils.isNotEmpty(apiName)) {
 return container.getCommonQuery(apiName).deleteBatch(ids, request);
 }
 return 0;
 }
 
 
 
 
 
 
 
 
 public int checkIsNameExist(String apiName, Long id, String name) throws Exception{
 if (StringUtils.isNotEmpty(apiName) && name!=null) {
 return container.getCommonQuery(apiName).checkIsNameExist(id, name);
 }
 return 0;
 }
 
 }
 
 | 
InterfaceContainer
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | @Service
 public class InterfaceContainer {
 @Resource
 private final Map<String, ICommonQuery> configComponentMap = new ConcurrentHashMap<>();
 
 public ICommonQuery getCommonQuery(String apiName) {
 return configComponentMap.get(apiName);
 }
 }
 
 
 | 
一个简单实现类
| 12
 3
 4
 5
 6
 7
 8
 
 | @Service("ypxx")public class YPSerice implements ICommonQuery {
 @Override
 public Object selectOne(Long id) throws Exception {
 return "YPSerice - selectOne 调用成功了";
 }
 
 
 
 | 
ResourceController
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | @RestController@Api(tags = {"资源接口-通用查询"})
 public class ResourceController {
 @Resource
 CommonQueryManager commonQueryManager;
 
 @GetMapping(value = "/{apiName}/info")
 @ApiOperation(value = "根据id获取信息")
 public Response info(@PathVariable("apiName") String apiName,
 @RequestParam("id") Long id,
 HttpServletRequest request) throws Exception {
 Map<String, Object> objectMap = new HashMap<String, Object>();
 Object obj = commonQueryManager.selectOne(apiName, id);
 objectMap.put("info", obj);
 return Result.ok(objectMap);
 }
 }
 
 | 
效果如下
