十四章 网关映射聚合信息查询实现

以封装 api-gateway-core 为目的,搭建 SpringBoot Starter 组件,用于服务注册发现的相关内容处理。

设计

14-设计

本章内容属于注册中心所需提供的接口,因为在服务发现模块中需要从网关注册中心拉取服务配置。这个服务配置其实就是各个 RPC 服务配置【系统、接口、方法】把这些信息拉取下来,注册到网关算力中,完成 RPC 映射的过程。

首先通过 gatewaydistribution 表,把网关和 RPC 应用服务关联起来,方便知道哪个网关算力处理哪些RPC映射管理。有了这个映射关系后,就可以把对应的 application_interface、application interface method、application systemn 三个表维护应用的配置信息关联起来了。

实现

【infrastructure层】网关配置仓储服务

1
2
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package cn.ray.gateway.center.infrastructure.repository;

import cn.ray.gateway.center.domain.manage.model.vo.*;
import cn.ray.gateway.center.domain.manage.repository.IConfigManageRepository;
import cn.ray.gateway.center.infrastructure.dao.*;
import cn.ray.gateway.center.infrastructure.pojo.*;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
* @author Ray
* @date 2023/5/23 14:59
* @description 网关配置仓储服务
*/
@Repository
public class ConfigManageRepository implements IConfigManageRepository {

@Resource
private IGatewayServerDao gatewayServerDao;

@Resource
private IGatewayServerDetailDao gatewayServerDetailDao;

@Resource
private IGatewayDistributionDao gatewayDistributionDao;

@Resource
private IApplicationSystemDao applicationSystemDao;

@Resource
private IApplicationInterfaceDao applicationInterfaceDao;

@Resource
private IApplicationInterfaceMethodDao applicationInterfaceMethodDao;

@Override
public List<GatewayServerVO> queryGateServerList() {
List<GatewayServer> gatewayServers = gatewayServerDao.queryGatewayServerList();
List<GatewayServerVO> gatewayServerVOList = new ArrayList<>(gatewayServers.size());
for (GatewayServer gatewayServer : gatewayServers) {
// 可以按照 IDEA 插件 vo2dto 方便转换
GatewayServerVO gatewayServerVO = new GatewayServerVO();
gatewayServerVO.setGroupId(gatewayServer.getGroupId());
gatewayServerVO.setGroupName(gatewayServer.getGroupName());
gatewayServerVOList.add(gatewayServerVO);
}
return gatewayServerVOList;
}

@Override
public boolean registerGatewayServerNode(String groupId, String gatewayId, String gatewayName, String gatewayAddress, Integer available) {
GatewayServerDetail gatewayServerDetail = new GatewayServerDetail();
gatewayServerDetail.setGroupId(groupId);
gatewayServerDetail.setGatewayId(gatewayId);
gatewayServerDetail.setGatewayName(gatewayName);
gatewayServerDetail.setGatewayAddress(gatewayAddress);
gatewayServerDetail.setStatus(available);
gatewayServerDetailDao.insert(gatewayServerDetail);
return true;
}

@Override
public GatewayServerDetailVO queryGatewayServerDetail(String gatewayId, String gatewayAddress) {
GatewayServerDetail req = new GatewayServerDetail();
req.setGatewayId(gatewayId);
req.setGatewayAddress(gatewayAddress);
GatewayServerDetail gatewayServerDetail = gatewayServerDetailDao.queryGatewayServerDetail(req);
if (null == gatewayServerDetail) {
return null;
}
// 可以按照 IDEA 插件 vo2dto 方便转换
GatewayServerDetailVO gatewayServerDetailVO = new GatewayServerDetailVO();
gatewayServerDetailVO.setGatewayId(gatewayServerDetail.getGatewayId());
gatewayServerDetailVO.setGatewayName(gatewayServerDetail.getGatewayName());
gatewayServerDetailVO.setGatewayAddress(gatewayServerDetail.getGatewayAddress());
gatewayServerDetailVO.setStatus(gatewayServerDetail.getStatus());
return gatewayServerDetailVO;
}

@Override
public boolean updateGatewayStatus(String gatewayId, String gatewayAddress, Integer available) {
GatewayServerDetail gatewayServerDetail = new GatewayServerDetail();
gatewayServerDetail.setGatewayId(gatewayId);
gatewayServerDetail.setGatewayAddress(gatewayAddress);
gatewayServerDetail.setStatus(available);
return gatewayServerDetailDao.updateGatewayStatus(gatewayServerDetail);
}

@Override
public List<String> queryGatewayDistributionSystemIdList(String gatewayId) {
return gatewayDistributionDao.queryGatewayDistributionSystemIdList(gatewayId);
}

@Override
public List<ApplicationSystemVO> queryApplicationSystemList(List<String> systemIdList) {
List<ApplicationSystem> applicationSystemList = applicationSystemDao.queryApplicationSystemList(systemIdList);
List<ApplicationSystemVO> applicationSystemVOList = new ArrayList<>();
for (ApplicationSystem applicationSystem : applicationSystemList) {
ApplicationSystemVO applicationSystemVO = new ApplicationSystemVO();
applicationSystemVO.setSystemId(applicationSystem.getSystemId());
applicationSystemVO.setSystemName(applicationSystem.getSystemName());
applicationSystemVO.setSystemRegistry(applicationSystem.getSystemRegistry());
applicationSystemVO.setSystemType(applicationSystem.getSystemType());
applicationSystemVOList.add(applicationSystemVO);
}
return applicationSystemVOList;
}

@Override
public List<ApplicationInterfaceVO> queryApplicationInterfaceList(String systemId) {
List<ApplicationInterface> applicationInterfaceList = applicationInterfaceDao.queryApplicationInterfaceList(systemId);
List<ApplicationInterfaceVO> applicationInterfaceVOList = new ArrayList<>();
for (ApplicationInterface applicationInterface : applicationInterfaceList) {
ApplicationInterfaceVO applicationInterfaceVO = new ApplicationInterfaceVO();
applicationInterfaceVO.setSystemId(applicationInterface.getSystemId());
applicationInterfaceVO.setInterfaceId(applicationInterface.getInterfaceId());
applicationInterfaceVO.setInterfaceName(applicationInterface.getInterfaceName());
applicationInterfaceVO.setInterfaceVersion(applicationInterface.getInterfaceVersion());
applicationInterfaceVOList.add(applicationInterfaceVO);
}
return applicationInterfaceVOList;
}

@Override
public List<ApplicationInterfaceMethodVO> queryApplicationInterfaceMethodList(String systemId, String interfaceId) {
ApplicationInterfaceMethod req = new ApplicationInterfaceMethod();
req.setSystemId(systemId);
req.setInterfaceId(interfaceId);
List<ApplicationInterfaceMethod> applicationInterfaceMethods = applicationInterfaceMethodDao.queryApplicationInterfaceMethodList(req);
List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOList = new ArrayList<>(applicationInterfaceMethods.size());
for (ApplicationInterfaceMethod applicationInterfaceMethod : applicationInterfaceMethods) {
ApplicationInterfaceMethodVO applicationInterfaceMethodVO = new ApplicationInterfaceMethodVO();
applicationInterfaceMethodVO.setSystemId(applicationInterfaceMethod.getSystemId());
applicationInterfaceMethodVO.setInterfaceId(applicationInterfaceMethod.getInterfaceId());
applicationInterfaceMethodVO.setMethodId(applicationInterfaceMethod.getMethodId());
applicationInterfaceMethodVO.setMethodName(applicationInterfaceMethod.getMethodName());
applicationInterfaceMethodVO.setParameterType(applicationInterfaceMethod.getParameterType());
applicationInterfaceMethodVO.setUri(applicationInterfaceMethod.getUri());
applicationInterfaceMethodVO.setHttpCommandType(applicationInterfaceMethod.getHttpCommandType());
applicationInterfaceMethodVO.setAuth(applicationInterfaceMethod.getAuth());
applicationInterfaceMethodVOList.add(applicationInterfaceMethodVO);
}
return applicationInterfaceMethodVOList;
}
}

【domain层】网关配置服务

1
2
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
package cn.ray.gateway.center.domain.manage.service;

import cn.ray.gateway.center.application.IConfigManageService;
import cn.ray.gateway.center.domain.manage.model.aggregates.ApplicationSystemRichInfo;
import cn.ray.gateway.center.domain.manage.model.vo.*;
import cn.ray.gateway.center.domain.manage.repository.IConfigManageRepository;
import cn.ray.gateway.center.infrastructure.common.Constants;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
* @author Ray
* @date 2023/5/23 14:40
* @description 网关配置服务
*/
@Service
public class ConfigManageService implements IConfigManageService {

@Resource
private IConfigManageRepository configManageRepository;

@Override
public List<GatewayServerVO> queryGatewayServerList() {
return configManageRepository.queryGateServerList();
}

@Override
public boolean registerGatewayServerNode(String groupId, String gatewayId, String gatewayName, String gatewayAddress) {
GatewayServerDetailVO gatewayServerDetailVO = configManageRepository.queryGatewayServerDetail(gatewayId, gatewayAddress);
if (null == gatewayServerDetailVO) {
try {
return configManageRepository.registerGatewayServerNode(groupId, gatewayId, gatewayName, gatewayAddress, Constants.GatewayStatus.Available);
} catch (DuplicateKeyException e) {
// 唯一索引冲突导致重复注册,则修改当前网关服务状态
return configManageRepository.updateGatewayStatus(gatewayId, gatewayAddress, Constants.GatewayStatus.Available);
}
} else {
// 找到对应网关信息,也修改网关服务状态
return configManageRepository.updateGatewayStatus(gatewayId, gatewayAddress, Constants.GatewayStatus.Available);
}
}

@Override
public ApplicationSystemRichInfo queryApplicationSystemRichInfo(String gatewayId) {
// 1. 查询出网关ID对应的关联系统ID集合。也就是一个网关ID会被分配一些系统RPC服务注册进来,需要把这些服务查询出来。
List<String> systemIdList = configManageRepository.queryGatewayDistributionSystemIdList(gatewayId);
if (null == systemIdList || systemIdList.size() == 0) {
return null;
}
// 2. 查询系统ID对应的系统列表信息
List<ApplicationSystemVO> applicationSystemVOList = configManageRepository.queryApplicationSystemList(systemIdList);
// 3. 查询系统下的接口信息
// 思考:这里的查询是一个不断地循环的查询,是否有办法优化下,减少查询次数。
for (ApplicationSystemVO applicationSystemVO : applicationSystemVOList) {
List<ApplicationInterfaceVO> applicationInterfaceVOList = configManageRepository.queryApplicationInterfaceList(applicationSystemVO.getSystemId());
for (ApplicationInterfaceVO applicationInterfaceVO : applicationInterfaceVOList) {
List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOS = configManageRepository.queryApplicationInterfaceMethodList(applicationInterfaceVO.getSystemId(), applicationInterfaceVO.getInterfaceId());
applicationInterfaceVO.setMethodList(applicationInterfaceMethodVOS);
}
applicationSystemVO.setInterfaceList(applicationInterfaceVOList);
}
return new ApplicationSystemRichInfo(gatewayId, applicationSystemVOList);
}
}
  1. 将 gateway_id 作为参数,获取表 gateway_distribution 中的网关和 RPC 应用服务绑定关系
  2. 从绑定信息中获取 system_id
  3. 根据 system_id 获取 RPC 应用服务信息、应用服务的接口信息
  4. 根据 systemid 和 interface id 获取接口方法信息

【interfaces层】网关配置管理;服务分组、网关注册、服务关联

1
2
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
package cn.ray.gateway.center.interfaces;

import cn.ray.gateway.center.application.IConfigManageService;
import cn.ray.gateway.center.domain.manage.model.aggregates.ApplicationSystemRichInfo;
import cn.ray.gateway.center.domain.manage.model.vo.GatewayServerVO;
import cn.ray.gateway.center.infrastructure.common.ResponseCode;
import cn.ray.gateway.center.infrastructure.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
* @author Ray
* @date 2023/5/23 15:25
* @description 网关配置管理;服务分组、网关注册、服务关联
*/
@RestController
@RequestMapping("/wg/admin/config")
public class GatewayConfigManage {

private Logger logger = LoggerFactory.getLogger(GatewayConfigManage.class);

@Resource
private IConfigManageService configManageService;

@GetMapping(value = "queryServerConfig", produces = "application/json;charset=utf-8")
public Result<List<GatewayServerVO>> queryServerConfig() {
try {
logger.info("查询网关服务配置项信息");
List<GatewayServerVO> gatewayServerVOList = configManageService.queryGatewayServerList();
return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), gatewayServerVOList);
} catch (Exception e) {
logger.error("查询网关服务配置项信息异常", e);
return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), null);
}
}

/**
* 注册网关服务节点
*
* @param groupId 分组标识
* @param gatewayId 网关标识
* @param gatewayName 网关名称
* @param gatewayAddress 网关地址
* @return
*/
@PostMapping(value = "registerGateway")
public Result<Boolean> registerGatewayServerNode(@RequestParam String groupId, @RequestParam String gatewayId, @RequestParam String gatewayName, @RequestParam String gatewayAddress) {
try {
logger.info("注册网关服务节点 gatewayId:{} gatewayName:{} gatewayAddress:{}", gatewayId, gatewayName, gatewayAddress);
boolean isSuccess = configManageService.registerGatewayServerNode(groupId, gatewayId, gatewayName, gatewayAddress);
return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), isSuccess);
} catch (Exception e) {
logger.error("注册网关服务节点异常", e);
return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), false);
}
}

@PostMapping(value = "queryApplicationSystemRichInfo", produces = "application/json;charset=utf-8")
public Result<ApplicationSystemRichInfo> queryApplicationSystemRichInfo(@RequestParam String gatewayId) {
try {
logger.info("查询分配到网关下的待注册系统信息(系统、接口、方法) gatewayId:{}", gatewayId);
ApplicationSystemRichInfo applicationSystemRichInfo = configManageService.queryApplicationSystemRichInfo(gatewayId);
return new Result<>(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getInfo(), applicationSystemRichInfo);
} catch (Exception e) {
logger.error("查询分配到网关下的待注册系统信息(系统、接口、方法)异常 gatewayId:{}", gatewayId, e);
return new Result<>(ResponseCode.UN_ERROR.getCode(), e.getMessage(), null);
}
}
}

测试

ApiTest

1
2
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
package cn.ray.gateway.center.test;

import cn.ray.gateway.center.application.IConfigManageService;
import cn.ray.gateway.center.application.IRegisterManageService;
import cn.ray.gateway.center.domain.manage.model.aggregates.ApplicationSystemRichInfo;
import cn.ray.gateway.center.domain.manage.model.vo.GatewayServerVO;
import cn.ray.gateway.center.domain.register.model.vo.ApplicationInterfaceMethodVO;
import cn.ray.gateway.center.domain.register.model.vo.ApplicationInterfaceVO;
import cn.ray.gateway.center.domain.register.model.vo.ApplicationSystemVO;
import com.alibaba.fastjson.JSON;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

/**
* @author Ray
* @date 2023/5/21 16:15
* @description
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApiTest {

private Logger logger = LoggerFactory.getLogger(ApiTest.class);

@Resource
private IConfigManageService configManageService;

@Resource
private IRegisterManageService registerManageService;

@Test
public void test_queryGatewayServerList() {
List<GatewayServerVO> gatewayServerVOS = configManageService.queryGatewayServerList();
logger.info("测试结果:{}", JSON.toJSONString(gatewayServerVOS));
}

@Test
public void test_registerGatewayServerNode() {
configManageService.registerGatewayServerNode("10001", "api-gateway-g1", "电商支付网关", "127.0.0.196");
configManageService.registerGatewayServerNode("10001", "api-gateway-g2", "电商支付网关", "127.0.0.197");
configManageService.registerGatewayServerNode("10001", "api-gateway-g3", "电商配送网关", "127.0.0.198");
}

@Test
public void test_registerApplication() {
ApplicationSystemVO applicationSystemVO = new ApplicationSystemVO();
applicationSystemVO.setSystemId("api-gateway-test");
applicationSystemVO.setSystemName("网关测试系统");
applicationSystemVO.setSystemType("RPC");
applicationSystemVO.setSystemRegistry("127.0.0.1");
registerManageService.registerApplication(applicationSystemVO);
}

@Test
public void test_registerApplicationInterface() {
ApplicationInterfaceVO applicationInterfaceVO = new ApplicationInterfaceVO();
applicationInterfaceVO.setSystemId("api-gateway-test");
applicationInterfaceVO.setInterfaceId("cn.ray.gateway.rpc.IActivityBooth");
applicationInterfaceVO.setInterfaceName("活动平台");
applicationInterfaceVO.setInterfaceVersion("v1.0.0");
registerManageService.registerApplicationInterface(applicationInterfaceVO);
}

@Test
public void test_registerApplicationInterfaceMethod() {
ApplicationInterfaceMethodVO applicationInterfaceVO01 = new ApplicationInterfaceMethodVO();
applicationInterfaceVO01.setSystemId("api-gateway-test");
applicationInterfaceVO01.setInterfaceId("cn.ray.gateway.rpc.IActivityBooth");
applicationInterfaceVO01.setMethodId("sayHi");
applicationInterfaceVO01.setMethodName("测试方法");
applicationInterfaceVO01.setParameterType("java.lang.String");
applicationInterfaceVO01.setUri("/wg/activity/sayHi");
applicationInterfaceVO01.setHttpCommandType("GET");
applicationInterfaceVO01.setAuth(0);
registerManageService.registerApplicationInterfaceMethod(applicationInterfaceVO01);

ApplicationInterfaceMethodVO applicationInterfaceVO02 = new ApplicationInterfaceMethodVO();
applicationInterfaceVO02.setSystemId("api-gateway-test");
applicationInterfaceVO02.setInterfaceId("cn.ray.gateway.rpc.IActivityBooth");
applicationInterfaceVO02.setMethodId("insert");
applicationInterfaceVO02.setMethodName("插入方法");
applicationInterfaceVO02.setParameterType("cn.ray.gateway.rpc.dto.XReq");
applicationInterfaceVO02.setUri("/wg/activity/insert");
applicationInterfaceVO02.setHttpCommandType("POST");
applicationInterfaceVO02.setAuth(1);
registerManageService.registerApplicationInterfaceMethod(applicationInterfaceVO02);
}

@Test
public void test_queryApplicationSystemRichInfo(){
ApplicationSystemRichInfo result = configManageService.queryApplicationSystemRichInfo("api-gateway-g4");
logger.info("测试结果:{}", JSON.toJSONString(result));
}
}

测试结果

14-测试

思考

  1. 网关注册中心除了一些核心的权重分配算法以外,其实大部分都在完成数据的接收写入库中和从库中读取配置到各个组件中进行使用。

  2. 在这段代码中,每次循环都去查询数据库,效率比较低,可以通过批量查询和适当的数据结构优化,减少查询次数。

    1
    2
    3
    4
    5
    6
    7
    8
    for (ApplicationSystemVO applicationSystemVO : applicationSystemVOList) {
    List<ApplicationInterfaceVO> applicationInterfaceVOList = configManageRepository.queryApplicationInterfaceList(applicationSystemVO.getSystemId());
    for (ApplicationInterfaceVO applicationInterfaceVO : applicationInterfaceVOList) {
    List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOS = configManageRepository.queryApplicationInterfaceMethodList(applicationInterfaceVO.getSystemId(), applicationInterfaceVO.getInterfaceId());
    applicationInterfaceVO.setMethodList(applicationInterfaceMethodVOS);
    }
    applicationSystemVO.setInterfaceList(applicationInterfaceVOList);
    }

    以下是一些优化的方法:

    1. 批量查询接口和方法信息:首先,收集需要查询的系统ID和接口ID,并使用批量查询语句一次性获取所有接口和方法信息。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      // 收集系统ID和接口ID
      List<String> systemIdList = new ArrayList<>();
      List<String> interfaceIdList = new ArrayList<>();

      for (ApplicationSystemVO applicationSystemVO : applicationSystemVOList) {
      systemIdList.add(applicationSystemVO.getSystemId());

      for (ApplicationInterfaceVO applicationInterfaceVO : applicationSystemVO.getInterfaceList()) {
      interfaceIdList.add(applicationInterfaceVO.getInterfaceId());
      }
      }

      // 批量查询接口信息
      List<ApplicationInterfaceVO> applicationInterfaceVOList = configManageRepository.queryApplicationInterfaceListBySystemIds(systemIdList);

      // 批量查询方法信息
      List<ApplicationInterfaceMethodVO> applicationInterfaceMethodVOList = configManageRepository.queryApplicationInterfaceMethodListByInterfaceIds(systemIdList, interfaceIdList);
    2. 构建数据结构:根据查询结果构建合适的数据结构,以便快速查找和关联接口和方法信息。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      // 构建接口ID和接口对象的映射关系
      Map<String, ApplicationInterfaceVO> interfaceMap = new HashMap<>();
      for (ApplicationInterfaceVO applicationInterfaceVO : applicationInterfaceVOList) {
      interfaceMap.put(applicationInterfaceVO.getInterfaceId(), applicationInterfaceVO);
      }

      // 关联方法信息到接口对象
      for (ApplicationInterfaceMethodVO applicationInterfaceMethodVO : applicationInterfaceMethodVOList) {
      String interfaceId = applicationInterfaceMethodVO.getInterfaceId();
      ApplicationInterfaceVO interfaceVO = interfaceMap.get(interfaceId);

      if (interfaceVO != null) {
      interfaceVO.getMethodList().add(applicationInterfaceMethodVO);
      }
      }

      // 关联接口列表到系统对象
      for (ApplicationSystemVO applicationSystemVO : applicationSystemVOList) {
      for (ApplicationInterfaceVO applicationInterfaceVO : applicationSystemVO.getInterfaceList()) {
      ApplicationInterfaceVO interfaceVO = interfaceMap.get(applicationInterfaceVO.getInterfaceId());
      if (interfaceVO != null) {
      applicationInterfaceVO.setMethodList(interfaceVO.getMethodList());
      }
      }
      }

    通过上述优化,首先进行批量查询获取所有接口和方法信息,然后根据查询结果构建数据结构,将接口和方法信息关联起来。这样可以避免多次循环查询,提高查询效率。

    请注意,上述代码仅提供了一种优化思路,具体实现可能需要根据业务需求和数据结构进行适当的调整。

不要总想着把问题留到最后

很多时候我会把编程和生活类比,会发现编程的问题其实也是抽象后的生活问题。就像我们并不能在生活总是想着把问题放到最后处理,人无远虑必有近忧,总是把问题放到最后,最后也就处理不过来了。

对于编程开发又何尝不是,如果你不停的从这复制点代码,从那粘贴点逻辑,想当然的编写着意想能一把梭哈的逻辑。那么最后就会是一片片的报错。即使在好用的单元测试在这个时候也没有太大作用,你只能花费大量的时候去梳理,你可能已经忘记了一天前写的代码逻辑。

问题越小才越容易被理解和处理。

生活如此,编程亦是如此。