# 原理分析之如何存储路由

SOP基于spring cloud，因此会涉及到网关路由。但是开发者不用去配置文件定义路由的隐射关系，SOP帮你解决了这个问题。

## 获取路由信息

网关启动成后会触发一个事件，代码见：`com.gitee.sop.gatewaycommon.config.AbstractConfiguration.listenEvent`

这个事件会取拉取微服务中提供的路由信息

下面以nacos为例，介绍拉取路由过程

1.从nacos中获取微服务实例

入口代码：`com.gitee.sop.bridge.route.NacosRegistryListener.onEvent`

2.拿到微服务信息，调用微服务提供的接口拉取路由数据

入口代码：`com.gitee.sop.gatewaycommon.route.BaseRegistryListener.pullRoutes`

最终落实到：`com.gitee.sop.gatewaycommon.route.ServiceRouteListener.onAddInstance`

微服务提供一个url：`http://ip:port/sop/routes`，对应Controller在：`com.gitee.sop.servercommon.route.ServiceRouteController.listRoutes`

微服务找到被`@Open`注解的方法，然后封装成一个路由对象，放到List中，最后返回给网关。

3.网关拿到路由信息，经过处理，转化成网关路由配置

关联方法：

`com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteCache.add`

`com.gitee.sop.gatewaycommon.gateway.route.GatewayRouteCache.refresh`


路由的存储方式是一个Map，key为路由id，即接口名+版本号。

```java
/**
 * key：nameVersion
 */
private static final Map<String, GatewayTargetRoute> routes = synchronizedMap(new LinkedHashMap<>());
```

因为客户端调用接口都会传递一个接口名和版本号，因此通过这两个字段能够很快查询出路由信息，然后进行路由转发操作。

