模块:native-cloud-common-dynamic-routes + native-cloud-system-argument

一、启动顺序

三者不是靠注解排序启动的,而是靠 “getBean 强制依赖” 形成先后顺序

DataSyncWorker  @PostConstruct init() ──getBean──> DynamicRoutesCache  setApplicationContext ──getBean──> DynamicArbHandler
   (Ordered=102)                          (Ordered=101)                          (Ordered=100)

实际创建/初始化顺序:

  1. DynamicArbHandler(先完成 afterPropertiesSet → 首次 doArb 选主)
  2. DynamicRoutesCache(后完成 @PostConstruct init → 注册轮询器 + 服务上下线监听)
  3. DataSyncWorker(最后完成 @PostConstruct init → 建立二进制客户端)

getOrder() 的 100/101/102 与依赖链方向一致,但 Spring 中 bean 创建顺序由依赖驱动,Ordered 在这里只是意图标识/列表排序用。

二、依赖关系

注册方式 依赖 强依赖点
DynamicArbHandler @EnableDynamicArb → Selector → DynamicArbConfiguration @Bean@ConditionalOnBean(NacosConfigService) NacosConfigService、NacosNamingService 不依赖另外两个
DynamicRoutesCache @EnableDynamicRoutes → Selector → DynamicRoutesConfiguration @Bean DiscoveryClient、DynamicArbHandler setApplicationContextgetBean(DynamicArbHandler.class)
DataSyncWorker @Component(组件扫描) RestTemplate、DynamicRoutesCache @PostConstruct init()getBean(DynamicRoutesCache.class)

三、加载时序流程图

sequenceDiagram participant APP as 启动类 participant IOC as Spring 容器 participant ARB as DynamicArbHandler
(Ordered=100, InitializingBean) participant ROUTE as DynamicRoutesCache
(Ordered=101) participant SYNC as DataSyncWorker
(Ordered=102) participant NACOS as Nacos 配置/注册中心 Note over APP: @EnableDynamicArb → DynamicArbHandlerSelector → DynamicArbConfiguration
@EnableDynamicRoutes → DynamicRoutesSelector → DynamicRoutesConfiguration
@Component 扫描 DataSyncWorker rect rgb(235,245,255) Note over IOC,ARB: ① DynamicArbHandler 初始化 IOC->>ARB: 创建 bean(先建 nacosConfigService) ARB->>ARB: 构造器 ARB->>ARB: setApplicationContext / setEnvironment ARB->>ARB: afterPropertiesSet() ARB->>ARB: getHost() / initConfig() / initService() ARB->>NACOS: 检查 config serverStatus == "UP" alt gatewayEnabled || multiPartitionNo ARB->>ARB: new MasterWatchingManager(32) end alt !gatewayEnabled(业务程序) ARB->>ARB: doArb(dataId, false) —— 首次选主 ARB->>NACOS: getConfig(dataId, group) 嗅探 ARB->>NACOS: publishConfigCas 竞选主分片 ARB->>ARB: 成功→updateConfigSchedule()
→ UpdateConfigManager.doPolling() 心跳刷新
失败→subscribe 实例监听,主下线时 doArb(dataId,true) end end rect rgb(240,255,240) Note over IOC,ROUTE: ② DynamicRoutesCache 初始化 IOC->>ROUTE: 创建 bean ROUTE->>ROUTE: 构造器(routes 缓存初始化) ROUTE->>IOC: setApplicationContext → getBean(DynamicArbHandler)
【强制依赖:若 ① 未完成,此处同步触发其完整创建】 ROUTE->>ROUTE: setEnvironment ROUTE->>ROUTE: @PostConstruct init() ROUTE->>ARB: 读取 multiPartitionNo / gatewayEnabled / extendApplicationList ROUTE->>ROUTE: updateDynamicRoutes() ROUTE->>ARB: registerWorker(serviceName, partitionNo)
→ MasterWatchingWorker(3000).doPolling() 定时轮询主分片 ROUTE->>NACOS: registerServiceEvent() → NotifyCenter 订阅 InstancesChangeEvent end rect rgb(255,250,235) Note over IOC,SYNC: ③ DataSyncWorker 初始化(参数系统场景) IOC->>SYNC: 创建 bean(@Component) SYNC->>SYNC: 构造器 / setApplicationContext SYNC->>IOC: @PostConstruct init() → getBean(DynamicRoutesCache)
【强制依赖:若 ② 未完成,此处同步触发其完整创建】 SYNC->>IOC: getBean(RestTemplate) SYNC->>SYNC: initWorkers() SYNC->>ROUTE: getExtendApplicationList() / getUriWithApplication() SYNC->>下游: GET /ringBufferInner/port → new ClientWorker(二进制通信客户端) end

四、关键机制说明

  • DynamicArbHandler 最先行DynamicRoutesCache.setApplicationContextgetBean(DynamicArbHandler.class) 会同步触发其完整创建,所以 afterPropertiesSet(含首次 doArb(false) 竞选)必然在 DynamicRoutesCache.init() 之前完成——这也是"启动期两次选举"问题的基础时序。
  • DynamicRoutesCache 承上启下:它从 DynamicArbHandler 拿模式标志(gatewayEnabled/multiPartitionNo/extendApplicationList),并在 updateDynamicRoutes() 中反向调用 registerWorker 给每个分片注册 MasterWatchingWorker 轮询器。
  • DataSyncWorker 最后:只有路由缓存和轮询器就绪后,initWorkers() 才能拿到"各分片主节点 URI",再调下游 /ringBufferInner/port 建二进制客户端;它只发主节点(备节点同步由主节点 redo 完成)。
  • MasterWatchingWorker.doPolling() 首次轮询已改为同样走 schedule 延时(2026-08-17 修改),不再 delay=0 立即触发,避免启动窗口期重复选举。

五、关键代码位置索引

组件 方法 位置
DynamicArbHandler afterPropertiesSet() native-cloud-common/native-cloud-common-dynamic-routes/src/main/java/com/huang/DynamicArbHandler.java 第 102 行
DynamicArbHandler doArb(String, boolean) 同文件第 145 行
DynamicArbHandler registerWorker(...) 同文件第 495 行
DynamicArbHandler MasterWatchingWorker.doPolling() 同文件第 872 行
DynamicRoutesCache setApplicationContext(getBean 强依赖) .../DynamicRoutesCache.java 第 97 行
DynamicRoutesCache @PostConstruct init() 同文件第 75 行
DynamicRoutesCache updateDynamicRoutes() / registerServiceEvent() 同文件第 117 / 205 行
DataSyncWorker @PostConstruct init() native-cloud-system-argument/src/main/java/com/huang/worker/DataSyncWorker.java 第 47 行
DataSyncWorker initWorkers() 同文件第 68 行