应用生命周期总览
受众:开发者 摘要:以「Spring Boot 是底层框架、SpringOpen 是上层应用开发框架」为主线,串起 SpringOpen 从启动到请求处理的完整生命周期,并标注每一段由谁负责。
SpringOpen 借鉴 Laravel 的应用生命周期开发体验,但不重造底层能力:
- Spring Boot 负责底层框架:IoC 容器、自动装配、属性源、HTTP 服务器、过滤器链、路由匹配、Actuator 运维端点、Liquibase 执行引擎等基础运行时。
- SpringOpen 负责上层开发体验:在 Spring Boot 之上提供模块规范、Provider 两阶段编排、
.env与配置约定、统一响应、Provider/Manager 可插拔能力、迁移命名约定、队列 / 调度 / 事件抽象和后台运维入口,让业务开发少配置、少概念、约定优先。
这条边界是 SpringOpen 的设计准则:能用 Spring / Spring Boot 原生承载的不重复造轮子,只在能显著降低业务开发成本的地方做上层封装。
Provider 四阶段模型
register()/boot()是启动期主链路;失败默认 fail-fast。ready()在ApplicationReadyEvent后执行,适合预热、补扫和上线宣告;失败只写报告和告警。shutdown()在ContextClosedEvent时按 boot 逆序执行,此时 Bean 尚未销毁,适合停止监听、关闭长连接、排空队列和清理静态门面。- 每个 provider 步骤都会写入
LifecycleReportduration,/actuator/lifecycle的阶段汇总可查看总耗时、最慢模块和失败数。详见 生命周期与容器 / shutdown 阶段。
启动到请求的完整顺序
| 阶段 | 发生了什么 | 负责层 | 详细文档 |
|---|---|---|---|
| 1. 进程启动 | StartupApplication(@SpringBootApplication)引导 Spring Boot | Spring Boot | — |
2. .env 加载 | ConfigDotenvEnvironmentPostProcessor 在 ConfigData 之前注入 .env | SpringOpen | 配置中心 |
| 3. 配置解析 | application.yml + spring.open.* + SpEL(#pascal() / #year())+ DB 运行时配置 | Spring Boot + SpringOpen | 配置中心 |
| 4. 自动装配引导 | LifecycleAutoConfiguration 引导,内建早装 data-redis / cache / config | SpringOpen | 生命周期与容器 |
5. Provider register() | 发现全部 ServiceProvider,按阶段 / order / 依赖排序,声明绑定 / schema / 标签 / 贡献项 / manifest | SpringOpen | 生命周期与容器 |
| 6. Bean 实例化 | 绑定物化为 BeanDefinition,交回 Spring 条件装配 | Spring Boot | — |
7. Provider boot() | 单例就绪后执行幂等运行时逻辑(读 ConfigManager、同步 schema、启动监听) | SpringOpen | 生命周期与容器 |
8. Provider ready() | 应用可服务后按 boot 顺序做预热、补扫、上线宣告 | SpringOpen | ready 阶段 |
| 9. 请求处理 | 过滤器链 → 路由 → Controller → 统一响应包装 | Spring MVC + SpringOpen | Web 规范 |
10. Provider shutdown() | 上下文关闭时按 boot 逆序停止监听 / 排空 / 注销 | SpringOpen | shutdown 阶段 |
.env 与配置加载
SpringOpen 内置 Laravel 风格的 .env 自动加载(ConfigDotenvEnvironmentPostProcessor),在 Spring Boot ConfigData 加载前运行,让端口、profile、数据源等启动期配置可参与后续解析。
- 默认扫描
./.env、../.env、./config/.env、./docker/.env等位置(支持.env与.env.properties),可通过spring.open.config.dotenv.locations追加。 - 优先级低于系统环境变量、JVM 参数和命令行参数:
.env只补默认值,不覆盖部署期显式配置。 - 运行时可覆盖配置走
config_entry(数据库)+ConfigManager,配置元数据走config_schema。
边界:属性源 / 绑定机制是 Spring Boot 原生能力;SpringOpen 只增加了 .env 自动加载和数据库运行时配置这两层上层约定。
Provider 扩展模型
模块通过 ServiceProvider 的 configure() / register() / boot() / ready() / shutdown() 入口接入生命周期,是 SpringOpen 对 Laravel Service Provider 的对应实现。完整说明见 生命周期与容器,要点:
- 发现走
@AutoService(ServiceProvider.class)+ServiceLoader(兼容spring.factories),对应 Laravel 的包自动发现。 register()只声明(绑定 / schema / 标签 / 贡献项 / manifest),boot()才执行运行时启动逻辑。ready()只放应用已可服务后的收尾动作,shutdown()只放跨模块顺序敏感的优雅收尾。- 推荐继承
ServiceProviderSupport写短入口;bind/singleton/tag/contribute/manifest/ready()/shutdown()等常用入口都有便捷写法。
HTTP 中间件
HTTP 横切分两层,边界清晰:
基础设施层(Spring 原生 Servlet Filter)——SpringOpen 提供默认实现并固定顺序,处理与具体路由无关的基础能力:
| 顺序 | 组件 | 职责 |
|---|---|---|
HIGHEST_PRECEDENCE | ConfigurableCorsFilter | 跨域处理 |
+1 | SecurityHeadersFilter | 安全响应头 |
+2 | TraceIdFilter | 链路 TraceId 注入与透传 |
+3 | ClientContextFilter | 客户端上下文(语言 / 设备 / GeoIP)解析 |
应用 / 路由层(SpringOpen 中间件层)——借鉴 Laravel route middleware,建立在 Spring HandlerInterceptor 之上,在路由命中后、Controller 执行前按「中间件组」施加到路由 path:
Middleware接口:handle(...)返回false短路请求(等价不调用$next),支持中间件参数(role:admin,editor)和terminate收尾回调(terminable middleware)。- 命名别名 + 中间件组:组按
path-patterns/exclude-patterns/order绑定路由,组内按序引用命名中间件。配置式(spring.open.web.middleware.groups)与编程式(MiddlewareRegistrar)皆可。 - 按处理方法施加:
@RouteMiddleware({"alias", "alias:params"})标注 Controller 类或方法(类级先于方法级),等价 Laravel 路由 / 控制器 middleware。 - 响应级:
ResultResponseBodyAdvice+GlobalExceptionHandler统一响应包装与异常转译;登录 / 权限仍走 Sa-Token@SaCheckLogin/@SaCheckPermission注解。
新增 HTTP 横切逻辑时:与路由无关的基础设施用 FilterRegistrationBean;按路由分组施加的业务横切声明一个 Middleware Bean 并加入中间件组。详见 Web 规范 的「中间件」章节。
同步业务编排另有三件套:spring-open-starter-execution(共享上下文)、spring-open-starter-hook(方法增强)、spring-open-starter-pipeline(固定步骤)、spring-open-starter-chain(显式 proceed 责任链),用于 Service 内部流程编排,不与 HTTP 中间件混用。
路由与请求 / 响应
- 路由是 Spring MVC 原生能力;SpringOpen 约定版本化前缀,通过
ApiRoutes.API_V1/ApiRoutes.ADMIN_V1与域常量派生/api/v1/{domain}/**、后台/api/v1/admin/{domain}/**。详见 Web 规范。 - 请求入参用 DTO + Validation,出参用 VO;Controller 不写业务逻辑。
- 响应由
ResultResponseBodyAdvice自动包装为统一Result,业务状态在Result.code,HTTP status 只表传输层;@IgnoreResponseWrapper可跳过包装。
迁移与 seed
- 执行引擎是 Liquibase(Spring Boot 启动时运行);SpringOpen 增加 Laravel 风格的可排序文件名约定与 schema / seed 分离规则。
- 命名形如
0000_00_00_<序号>_<owner>_<action>.xml(基线)/<yyyy_MM_dd_HHmmss>_<owner>_<action>.xml(增量),按 starter / core / module / install 拓扑分区。 - schema changeSet 与 seed changeSet 分文件维护,约定见 数据库 与工程约定。
命令行与运维入口
SpringOpen 不复刻 artisan 的全部运维命令,而是按边界分工:
| 需求 | 入口 | 说明 |
|---|---|---|
| CLI / 代码脚手架 | spring-open list / about / actuator:status / config:list / route:list / module:list / migrate:list / migrate:status / migrate:run / seed:run / queue:* / schedule:* / make:crud(CLI / Codegen) | SpringOpen 上层能力:项目内省、配置前缀巡检、Controller 路由源码巡检、Actuator 运行态只读 smoke、Queue / Scheduler Admin API 薄封装、迁移源码 / changeSet 巡检、显式 JDBC + Liquibase 迁移执行、CRUD 后端 / Admin / 迁移 / 菜单权限 / 文档全链路预览;CLI 命令可通过 CliCommandProvider + @AutoService 被模块发现 |
| 数据库迁移执行 | Liquibase(启动时自动执行)/ spring-open migrate:run / spring-open seed:run | 默认交给 Spring Boot + Liquibase;CLI 执行入口仅在显式 JDBC、显式 --confirm 时运行,并保持 DATABASECHANGELOG filename 与应用启动迁移一致 |
| 运行时内省 | Actuator /actuator/lifecycle、/actuator/env、/actuator/mappings、/actuator/health | 模块编排 / 配置 / 路由 / 健康均走 Spring Boot Actuator |
| 模块声明内省 | /actuator/lifecycle 的 manifests / contributions | 各模块 manifest 与贡献项声明的统一只读消费方 |
| 开发运维脚本 | ./.ai/scripts/*、./scripts/docker | 仓库内工程脚本 |
/actuator/lifecycle 是 SpringOpen 模块视角的运行时内省入口(类比 php artisan about):它读取生命周期报告,并聚合各模块在 register() 阶段声明的 manifest 与贡献项,确保这些声明面始终有可观测的消费者。需要业务级落库(如把 manifest 权限 / 菜单同步进 IAM)时,由 owning module 注入 ModuleManifestRegistry 在 boot() 阶段按自身规则消费。
Laravel 概念对照
| Laravel | SpringOpen | 负责层 |
|---|---|---|
| bootstrap / kernel | StartupApplication + lifecycle 引导 | Spring Boot + SpringOpen |
| service provider register/boot | ServiceProvider.register() / boot() | SpringOpen |
| package auto-discovery | @AutoService + ServiceLoader | SpringOpen |
config / .env | ConfigDotenvEnvironmentPostProcessor + ConfigManager | SpringOpen(基于 Spring Boot 属性源) |
| global middleware | Servlet Filter(CORS / SecurityHeaders / TraceId / ClientContext) | Spring 原生 + SpringOpen 默认实现 |
| route middleware / groups | Middleware + 命名别名 + 中间件组(spring.open.web.middleware / MiddlewareRegistrar,基于 HandlerInterceptor) | SpringOpen |
| routing / controller | Spring MVC + ApiRoutes 版本化约定 | Spring MVC + SpringOpen |
| request / response | Result + ResultResponseBodyAdvice + GlobalExceptionHandler | SpringOpen |
| event / listener | spring-open-starter-event + Outbox | SpringOpen |
| model events / observer | BaseService 写入闭环触发 ModelObserver + ModelEvent(database starter) | SpringOpen |
| gate / policy / authorize | Gate Facade + Policy<T> + GateBeforeCheck(auth starter,资源实例级授权,与 Sa-Token 权限串互补) | SpringOpen |
| form request | FormRequest + FormRequestBodyAdvice(webmvc starter,校验前规范化 + 授权,包 Bean Validation) | SpringOpen |
| api resource / include | ResourceIncludes(webmvc starter,?include= 条件关系展开,配合可空字段 + @JsonInclude(NON_NULL)) | SpringOpen |
| queue / job | spring-open-starter-queue(Provider 模型) | SpringOpen |
| scheduler | spring-open-starter-scheduler(Provider 模型) | SpringOpen |
| migration / seeder | Liquibase + 可排序命名 / schema-seed 分离 | Spring Boot + SpringOpen |
| artisan command | spring-open CLI(ServiceLoader 命令发现 + 脚手架)+ Actuator + Liquibase(运维) | Spring Boot + SpringOpen |
| route:list | /actuator/routes 路由内省端点(webmvc starter,方法 + 路径 + 处理器 + operationId + 权限码 + 中间件) | SpringOpen |