前两篇解决了”为什么”和”怎么跑起来”,这一篇把 JHipster 9.x 生成的技术栈摊开讲清楚。我们的观点是:用 JHipster 不只是用它的生成能力,更是接受它替你做的一整套选型——这些选型之间互相咬合,理解了咬合点,后面遇到任何问题都知道往哪查。
全景图
先上一张图,后面每一节展开一个区块:
flowchart TB
subgraph client["前端(WebApp)"]
NG["Angular 21<br/>Zoneless / signals<br/>(或 React 19 / Vue)"]
NG -->|"#swagger-ui / OIDC 登录页"| NG
end
subgraph server["后端(Spring Boot 4 / Java 21)"]
REST["REST 资源层<br/>web/rest"]
SEC["Spring Security<br/>JWT / OAuth2 / Session"]
SVC["Service 层<br/>业务逻辑 + DTO(MapStruct)"]
REPO["Spring Data JPA<br/>Repository"]
HC["Hazelcast / Redis<br/>缓存"]
LIQ["Liquibase<br/>数据库迁移"]
end
subgraph data["数据"]
H2["H2(dev)"]
PROD["MySQL / PostgreSQL<br/>(prod)"]
ES["Elasticsearch(可选 search)"]
end
subgraph build["构建与工具链"]
MVN["Maven 3.9 / Gradle 9.4"]
VITE["Vite dev server"]
TEST["JUnit 5 + Testcontainers<br/>+ Cypress"]
end
NG -->|"Vite 代理 /api -->:8080"| REST
REST --> SEC
REST --> SVC
SVC --> REPO
SVC --> HC
REPO --> LIQ --> PROD
LIQ --> H2
SVC -.可选.-> ES
MVN --- server
VITE --- client
TEST --- server
后端:Spring Boot 4 体系
Spring Boot 4 与 Java 21
JHipster 9.x 基于 Spring Boot 4.0.x,Java 21 是最低要求(Java 25 已支持)。Java 21 的 records、sealed classes、switch 模式匹配在日常业务代码里都很实用;Spring Boot 4 这边的升级里与我们最相关的是 Spring Security 的调整——WebSocket 安全配置迁移到了 EnableWebSocketSecurity(第 8 篇会讲认证部分受影响的配置)。另外 GraalVM 原生镜像支持更成熟,Maven 体系下用 spring-boot:graalvm 即可走原生编译,启动时间与内存占用对部署小实例很有价值。
分层与 MapStruct
生成的分层是教科书式的:Resource(Controller)→ Service → Repository,DTO 与实体之间用 MapStruct 做映射:
@Mapper(componentModel = "spring")
public interface CustomerMapper extends EntityMapper<CustomerDTO, Customer> {
CustomerDTO toDto(Customer customer);
Customer toEntity(CustomerDTO customerDTO);
default Customer fromId(Long id) {
if (id == null) return null;
Customer c = new Customer();
c.setId(id);
return c;
}
}
MapStruct 在编译期生成实现类,没有反射开销,类型不匹配直接编译报错。配合 JDL 里的 dto * with mapstruct 注解,实体一变 mapper 同步再生成。
Spring Data JPA
Repository 层是标准 Spring Data JPA,生成时已带好分页排序支持(PersistenceAuditEntityListener 还会给实体加审计字段)。JHipster 的默认约定值得遵守:REST 层不直接碰实体,一律走 DTO——这避免了懒加载关联在序列化时炸出 LazyInitializationException,也避免了把敏感字段泄给前端。
前端:Angular 21(React 19 一句话)
我们主线选 Angular。JHipster 9 生成的 Angular 21 是相当”新派”的代码:Zoneless 默认(无 zone.js,变更检测由 signals 驱动)、组件默认 standalone、迁移中的 signals/httpResource 数据获取模式、可选 Vitest 测试器。目录在 src/main/webapp/app/ 下,按 feature 组织(admin、account 等模块),共享逻辑在 core/shared。
HTTP 访问统一走生成的服务类(继承自 Resource 模式的 REST 客户端),认证 token 注入、错误处理、i18n 都已在基础设施里。React 19(配 react-bootstrap)是另一个一等选项,生成质量同样很高——但如果团队没有强偏好,选 Angular 能吃到 JHipster 社区最厚的积累(它一直是 JHipster 的默认前端)。
数据:H2 开发,生产 MySQL/PostgreSQL
JHipster 的数据库策略是”dev 与 prod 分离,迁移统一”:
| 环境 | 数据库 | 说明 |
|---|---|---|
| dev | H2(内存或磁盘) | 零安装,./mvnw 直接跑;也可在浏览器开 H2 Console 查数据 |
| prod | MySQL / PostgreSQL(生成时选定) | application-prod.yml + SPRING_DATASOURCE_* 环境变量注入 |
两套数据库能共用同一份迁移脚本,靠的是 Liquibase 的抽象(下一节)。我们团队实践:dev 用 H2 图省事,但 CI 里用 Testcontainers 起真 PostgreSQL 跑集成测试(第 17 篇),避免”H2 上绿的、PG 上红的”。如果生成时给实体声明了 search,还会额外接上 Elasticsearch。
迁移:Liquibase
所有表结构变更都通过 src/main/resources/config/liquibase/ 下的 changelog 管理:master.xml 汇总,changelog/00000000000000_initial.xml 是初始结构,之后每次实体变更追加新 changeset。应用启动时 Liquibase 自动检查并执行未运行的 changeset。这套机制重要到第 7 篇要整篇讲,这里只强调一句:它是 JHipster 项目数据库一致性的基石,任何”手动改表”的行为都是事故的开始。
构建与工具链
- Maven 3.9 / Gradle 9.4 二选一(生成时确定)。我们用 Maven:
./mvnw开发、./mvnw -Pprod package打生产包(含前端构建)、./mvnw verify跑全部测试。wrapper 提交进版本库,团队成员不需要本机装 Maven。 - 前端构建走 package.json 脚本,dev 时 Vite dev server 监听 9000 并把
/api代理到 8080,prod 时打进 jar 一起部署。 - 测试:后端 JUnit 5 + Testcontainers(IT 起真实数据库),前端可选 Cypress 端到端。
- Docker:生成 Dockerfile,
jib或./mvnw -Pprod package -Pe2e配套,是第 18 篇 CI/CD 的基础。
开箱即用的运维能力
技术栈里还有一批”第一天就有、手搭项目最后也没补上”的运维件,值得单列:
- Spring Boot Actuator + Micrometer:
/management/health、/management/metrics等端点已配好权限与暴露策略,JVM、HTTP、数据库连接池指标齐备; - 管理前端页面:登录 admin 后直接看 Metrics(含各端点 QPS 与耗时分布)、Health、Configuration(运行时配置)、Audits(实体变更审计)、Logs(动态调日志级别);
- API 文档:springdoc 集成,
/swagger-ui里全部 REST 端点可在线调试(带认证授权),前后端联调与接口评审省大量沟通; - 审计跟踪:实体的增改由
PersistenceAuditEntityListener记录到jhi_persistent_audit表,配合页面可查”谁在什么时候改的”。
这块的完整展开在第 20 篇(可观测性),这里先记住:这些不是插件,是生成栈的一部分。
i18n 与国际化
前后端双端国际化都是标配:后端消息与邮件模板按 locale 解析,前端每个页面/实体都有 i18n 资源文件(i18n/zh-cn/*.json 等),生成时自带几十种语言骨架。国内项目常忽略它,直到某天要出海或做多语言客户——那时它的价值就显出来了(第 27 篇专讲)。
profile 体系
JHipster 用 Spring profile 组织配置:application-dev.yml(宽松日志、H2、热重载)与 application-prod.yml(生产数据库、性能取向)。本地覆盖用 application-local.yml(默认加入 gitignore,适合放个人数据库连接),微服务场景还有 Spring Cloud Config 统一下发。这套体系的完整玩法在第 21 篇。
版本基线速查
JHipster 9.x(2026 年 3 月发布,当前 9.2)整条栈的版本口径,选型对齐时直接抄:
| 组件 | 版本/要求 |
|---|---|
| Java | 21 必须(Java 25 已支持,Java 17 淘汰) |
| Spring Boot | 4.0.x |
| Angular | 21(Zoneless 默认);React 19 / Vue 为等价选项 |
| Node | 22 必须 |
| 构建工具 | Maven 3.9 / Gradle 9.4 |
| 生成器 | generator-jhipster 9.x(TypeScript 重写,yeoman-generator v8) |
小结
- 后端:Spring Boot 4 + Java 21,
Resource → Service → Repository分层,DTO 用 MapStruct 编译期映射。 - 前端:Angular 21 Zoneless/signals 为主线,React 19 为等价选项。
- 数据:dev H2、prod MySQL/PostgreSQL,结构演进统一交给 Liquibase。
- 构建:Maven/Gradle + Vite + JUnit 5/Testcontainers/Cypress,profile 管理 dev/prod/local 三套配置。
- 这套栈的价值在于互相咬合:JDL 改实体,后端、DTO、Liquibase、前端、测试同步再生成。
系列导航
- 上一篇:环境搭建与第一个应用
- 下一篇:开发工作流——热重载与前后端联调
- 延伸阅读:数据库迁移——Liquibase 不是可选项 · 安全体系(上)——认证