后端启动:Spring Boot 怎么 boot
昨天看了全景,今天钻进后端的"开机流程":从 main 方法一路到"连上 K8s、把 SDK 各服务注册成 Bean"。最关键的一步是 SdkConfig 的 @PostConstruct——这是 console 和 sdk 的桥接点。
SdkConfig 的 @PostConstruct 真正连上 K8s 档案室)→ 挂好挡(各 SDK 服务注册成 Bean)→ 仪表亮起(静态资源就绪)→ 怠速待命(Tomcat 监听 8080)。今天最关键的一颗螺丝就是那个"接通档案室"的 @PostConstruct。主类与组件扫描
入口 console/HigressConsoleApplication.java:18-23:
@SpringBootApplication(scanBasePackages = {"com.alibaba.higress"})
public class HigressConsoleApplication {
public static void main(String[] args) {
SpringApplication.run(HigressConsoleApplication.class, args);
}
}
ConfigServiceImpl 上带 @Service),它们的包是 com.alibaba.higress.console.service 之外的。把扫描根设为 com.alibaba.higress,就能同时覆盖 console 和 sdk 两个模块的包,让两边的 Bean 都被发现。application.properties
console/src/main/resources/application.properties(注意:只有 .properties,没有 .yaml):
springdoc.api-docs.enabled=false # 默认关闭 API 文档
springdoc.pathsToMatch=/v1/**,/session/**,/dashboard/**,/system/**,/user/**
higress-console.build.version=@app.build.version@ # Maven 资源过滤注入版本
server.compression.enabled=true # 开启响应压缩
pathsToMatch 这一行等于把后端全部 API 前缀列了个总览:/v1(业务资源)、/session(登录)、/dashboard、/system、/user。@app.build.version@ 会被 Maven 替换成 console/pom.xml:20 的 2.1.0。大量运行期参数不写死在这里,而走 @Value + 环境变量(Helm 注入),见 L06。WebMvc 与 SPA 回退
console/WebMvcInitializer.java:31-59(@Configuration @EnableWebMvc)做两件事:把 /* 映射到 classpath:/static/(打包进来的前端),并实现 SPA 回退:
// resolveResourceInternal :48-56(简化)
// 找不到的资源:只要不是 /v1/ API 前缀(:35),
// 也不是 /assets/ /css/ /js/ 等静态目录(:39-40),
// 一律回退到 /index.html
/route、/plugin)都在浏览器里由 JS 处理,服务器上并没有这些文件。如果用户直接刷新 /plugin,服务器找不到这个文件会 404。SPA 回退就是"找不到就统统返回 index.html",让前端 JS 接管路由。但要排除真正的 API(/v1/)和静态资源目录,否则 API 也被吞成 HTML 就乱套了。resolveResourceInternal:| 浏览器请求 | 命中哪条规则 | 服务器返回 |
|---|---|---|
GET /v1/routes | 是 /v1/ API 前缀(:35) | 交给后端控制器,返回 JSON |
GET /assets/app.js | 是静态目录(:39-40) | 返回该静态文件 |
GET /plugin(刷新页面) | 都不是 → 兜底 | 返回 /index.html,前端 JS 接管路由 |
SdkConfig:真正连上 K8s 的地方
整个启动流程最关键的 Bean 是 console/config/SdkConfig.java(@Configuration):
// :47-79 一组 @Value 读入 K8s/controller 连接参数
@Value("${higress-console.kube-config:}") private String kubeConfig;
@Value("${higress-console.controller.service.host:...}") private String controllerServiceHost;
// ... jwtPolicy、accessToken、clusterDomainSuffix 等,默认值来自 HigressConstants
// :83-93 @PostConstruct initialize()
@PostConstruct
public void initialize() {
HigressServiceConfig config = HigressServiceConfig.builder()
.withKubeConfigPath(...)....build();
serviceProvider = HigressServiceProvider.create(config); // ← 这一步真正连 K8s
}
@PostConstruct 表示"这个 Bean 构造完成后立刻执行 initialize()"。它用 @Value 注入的参数搭出一个 HigressServiceConfig,然后 HigressServiceProvider.create(config)——从这一刻起,后端就握着一个能读写 K8s 的客户端了。(Provider 内部怎么装配,第 2 周 Day 06 详讲。)👶 小白:为什么"连 K8s"要放在 @PostConstruct,不直接写在构造函数里?
👨🏫 老师:因为构造 Bean 时,那些 @Value 注入的参数(kubeConfig、controller 地址…)还没被 Spring 填进来——构造函数里读到的全是 null。@PostConstruct 的时机是"对象造好、依赖也都注入完之后",这时参数齐了,才能拿它们去搭 HigressServiceConfig 连档案室。就像点火前得先等钥匙插到位、油路接通,急不得。
@Bean 桥接:console ← sdk
SdkConfig.java:95-168 把 serviceProvider 产出的各 SDK 服务注册成 Spring @Bean:
@Bean public RouteService routeService() { return serviceProvider.routeService(); }
@Bean public KubernetesClientService kubernetesClientService() { ... }
@Bean public WasmPluginService wasmPluginService() { ... }
@Bean public AiRouteService aiRouteService() { ... }
// ServiceService / DomainService / LlmProviderService / McpServerService ...
SdkConfig 就充当"接线板"——把 sdk 造出来的每个 service 挂到 Spring 容器里。之后 console 的控制器只要 @Resource RouteService routeService 就能拿到,任何 K8s 操作都从这里走,控制器自己从不 new。配置键 SystemConfigKey
所有可注入的配置键定义在 console/constant/SystemConfigKey.java:
:25ns(命名空间)、:29controller.access-token、:31controller.jwt-policy:33 / :35controller.service.port / host、:51config-map.name、:74+dashboard.*
HIGRESS_CONSOLE_*)注入容器,Spring 再通过 @Value 读进来。所以"改配置"= 改 Helm values → 环境变量 → @Value,无需改代码。Day 19 会把这条注入链走完。启动时序(串起来)
main() → SpringApplication.run
→ 组件扫描 com.alibaba.higress(console + sdk 的 @Component/@Service)
→ 加载 application.properties + 环境变量(@Value)
→ SdkConfig 构造 → @PostConstruct:建 HigressServiceConfig → create(provider) → 连 K8s
→ 注册各 SDK service 为 @Bean
→ WebMvcInitializer 装好静态资源 + SPA 回退
→ 内嵌 Tomcat 监听 8080,就绪
今日小结 + 动手
🧠 今天你应该能回答
- 为什么
scanBasePackages要设成com.alibaba.higress? - SPA 回退解决什么问题?为什么要排除
/v1/? SdkConfig的@PostConstruct干了什么?它为什么是"桥接点"?- 配置怎么从 Helm 一路走到
@Value?
✋ 动手
cd /Users/bitmart/work/codes/github/higress-group/higress-console/backend
sed -n '18,23p' console/src/main/java/com/alibaba/higress/console/HigressConsoleApplication.java
sed -n '31,59p' console/src/main/java/com/alibaba/higress/console/WebMvcInitializer.java
sed -n '47,168p' console/src/main/java/com/alibaba/higress/console/config/SdkConfig.java