探寻spring mvc客户端初始化接入soul至入库的流程
目录
一、soul的数据流综述
下面是现阶段对于soul网关的数据流的一个综述图(不含getway/Admin集群的数据流)
整体的数据流大致分为如下几个流程
- clients初始化注册至soul-admin,并存储至数据库中流程(☆☆)
- 后台管理页面CURD配置至soul-admin,并存储至数据库流程(☆)
- soul-admin的数据库数据同步到soul-getway中流程(☆☆☆)
- 用户请求soul-getway,soul-getway的内部整体处理流程(☆☆☆)
- soul-admin和clients之间的服务检测流程(☆☆)
- 每个插件的内部处理流程(☆☆)
今天分析第一个流程,也就是clients初始化注册至soul-admin,并存储至数据库中的流程,也就是下面这一条线
二、客户端的流程
2.1 接入soul网关的流程回顾
前面已经讲过一个sprintboot/spring mvc项目如何接入soul网关,大致的流程如下
- pom.xml里引入soul-spring-boot-starter-client-springmvc依赖
- yml中增加相应的网关配置(网关url、项目端口、contextpath、服务名称、是否代理整个服务)
- 服务中需要的接口增加注解@SoulSpringMvcClient
- 启动服务,成功接入网关
2.2 soul-spring-boot-starter-client-springmvc里到底有什么
查看soul-spring-boot-starter-client-springmvc的maven依赖关系树如下所示
一共soul自己的包也只有三个,大体看下这三个的源码
- soul-client-springmvc(springmvc核心,注解及注解的处理流程)
- soul-client-commen(没什么重要的货,没有逻辑,先忽略)
- soul-common(soul的公共定义,没有逻辑,先忽略)
2.3 debug几个方法入口
盲猜也能猜到处理逻辑在SpringMvcClientBeanPostProcessor
- SpringMvcClientBeanPostProcessor–负责客户端接口信息(rule)的注册
看代码负责yml配置信息的初始化,这个方法在soul-spring-boot-starter-client-springmvc注入的时候就会被调用
在SpringMvcClientBeanPostProcessor处打断点,启动客户端服务,进入断点
这个方法知识初始化了url,executorService和配置信息,并没有发送。
- postProcessAfterInitialization()
看代码猜测是发送注册信息和使用注解的接口方法
(1) postProcessAfterInitialization这个方法是BeanPostProcessor中的方法,查阅了一下,这个方法主要是为了
public interface BeanPostProcessor {
//bean初始化方法调用前被调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//bean初始化方法调用后被调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
明白了这个是在项目bean初始化之后做一些操作,猜测是遍历整个注入的beans,根据条件找出我们需要的,验证一下,打点日志,验证了这个假设(感觉有优化方法,如果项目bean很多的话会有点耗时)
(2) 中间判断过程忽略(大体是根据两层过滤,一层是不是Controller/RestController/Mapping注解,二层是根据是不是SoulSpringMvcClient注解)
(3) 在线程池执行处打断点,如下将接口信息,路径信息,协议类型信息等拼装成所需格式
第一个executorService.execute是为了当SoulSpringMvcClient的prePath上有**(indexOf(*)>1),代表着注册该controller所有,不需要做方法级别的注册信息。
第二个executorService.execute是为传输prePath没有**,方法级别的接口注册信息。
(4) 使用okHttp进行传输注册信息至soul-admin
- ContextRegisterListener–负责配置信息的注册,流程和SpringMvcClientBeanPostProcessor基本一样
- 差异仅在于实现方式不太一样
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
//bean初始化方法调后调用
void onApplicationEvent(E var1);
}
- 作用有些差异,如果配置是full,则全局contextPath/**注册至soul-admin
三、客户端到服务端
- 使用okhttp
- http协议传输
四、soul-admin的流程
4.1 客户端的来信
- url:http://localhost:9095/soul-client/springmvc-register
- registerDTO
4.2 soul-admin的处理流程
- 找到springmvc-register这个前缀的处理入口
下面比较简单不做详细介绍 - registerSpringMvc(final SpringMvcRegisterDTO dto)
- handlerSpringMvcRule(final String selectorId, final SpringMvcRegisterDTO dto)
- private void registerRule(final String selectorId, final String path, final String rpcType, final String ruleName)
- register(RuleDTO ruleDTO)
- 至此入库 selector 和rule
7 publishEvent(ruleDO, ruleConditions);-----这个应该就是明天的第二个数据流,数据同步的数据入口
五、疑问点
- debug中,ContextRegisterListener比SpringMvcClientBeanPostProcessor的时间靠后出发,感觉这个顺序可以颠倒一下,以免做无用的检测。