这本书写给谁
这本书写给三类人。
第一类:刚读完《Java 编程入门》,想接着做项目。 你会写类、集合、Stream、异常和 JUnit,也能用 Maven 打出一个可执行 jar,但还没有把程序接到数据库、暴露成 HTTP 服务、部署成容器的经验。这本书按顺序补上这些。
第二类:会 Java,但没做过服务端。 你可能写过桌面工具、批处理脚本或 Android 应用,知道 Java 语法,但对连接池、事务、索引、线程池、可观测性这些服务端概念只有零散印象。书里不会重新讲语法,会从工程问题切入。
第三类:做过 Spring Boot,想看清框架替你做了什么。 你能用 @Transactional、@Valid、Actuator 把服务搭起来,但遇到「事务为什么没回滚」「校验为什么没触发」「指标为什么没有」时说不清原因。这本书用 Javalin 和手写装配把同样的位置实现一遍,附录 D 再对照 Spring Boot。
如果你还不会 Java 的基础语法,建议先读卷一。卷二默认你能读懂 record、泛型、Lambda、Stream 和异常体系,不会再解释这些。
前置知识
除了 Java 语言本身,还需要三件事:
- 会用 Maven。 知道
pom.xml、依赖作用域、mvn test和mvn package的区别。第 1 章会讲多模块,但不从零讲 Maven。 - 写过基础 SQL。 知道
select、insert、update、delete、join和where。索引、执行计划和事务会在第 4、5 章展开。 - 会用命令行和 Docker。 知道
cd、环境变量、curl,能运行docker run并看懂端口映射。数据库实验都在容器里做,不要求本机安装 PostgreSQL。
不需要提前会 Javalin、Jackson、HikariCP 或 Testcontainers。这些库会在用到的那一章从零开始讲。
本书结构
全书 55 篇,分六个部分:
| 部分 | 章节 | 解决的问题 |
|---|---|---|
| 一、工程基座 | 1–2 | 多模块、依赖治理、静态分析与质量门禁 |
| 二、数据访问 | 3–6 | JDBC、连接池、schema、索引、事务、JSON |
| 三、HTTP 服务 | 7–8 | 路由、中间件、校验、错误契约、优雅停机 |
| 四、并发与异步 | 9–11 | 线程池、虚拟线程、CompletableFuture、定时任务 |
| 五、可观测性与缓存 | 12–14 | 日志、指标、追踪、健康检查、Caffeine、Redis |
| 六、测试与交付 | 15–16 | Testcontainers、端到端测试、镜像、发布与回滚 |
章节之间有依赖。第 3 章的仓储依赖第 1 章的模块边界,第 5 章的事务依赖第 3 章的连接池,第 13 章的指标依赖第 7 章的中间件。跳章可以,但不要跳过第 3、5、7 章直接看第 15 章。
环境清单
本书的写作与验证环境:
| 项 | 版本 | 说明 |
|---|---|---|
| 操作系统 | macOS 26.3(arm64) | Linux 命令基本一致;Windows 需替换路径分隔符 |
| JDK | Temurin 25.0.5+8(LTS) | JAVA_HOME=~/.jdks/jdk-25.0.5+8/Contents/Home |
| Maven | 3.9.12 | mvn -version 的 Java 版本应为 25.0.5 |
| Docker | 29.7.2(客户端) | 用于 PostgreSQL、Redis 与 Testcontainers |
| PostgreSQL | 17.11(容器 postgres:17-alpine) | 本机不要求安装数据库 |
| 终端 | zsh | bash 也可;Windows 用 PowerShell 时注意引号 |
| 编码 | UTF-8 | JDK 18 起默认 UTF-8,SQL 文件仍显式声明 |
检查命令:
java -version
javac -version
mvn -version
docker --version
docker run --rm postgres:17-alpine postgres --version
本机真实输出:
openjdk version "25.0.5" 2026-10-20 LTS
OpenJDK Runtime Environment Temurin-25.0.5+8 (build 25.0.5+8-LTS)
OpenJDK 64-Bit Server VM Temurin-25.0.5+8 (build 25.0.5+8-LTS, mixed mode, sharing)
javac 25.0.5
Apache Maven 3.9.12 (848fbb4bf2d427b72bdb2471c22fced7ebd9a7a1)
Maven home: /Users/bingrong.yan/apache-maven-3.9.12
Java version: 25.0.5, vendor: Eclipse Adoptium, runtime: /Users/bingrong.yan/.jdks/jdk-25.0.5+8/Contents/Home
Docker version 29.7.2, build a7dcaa6fdb
postgres (PostgreSQL) 17.11
mvn -version 里的 Java version 必须和 java -version 一致。不一致时先检查 JAVA_HOME 与 PATH,不要急着往下读——Maven 用错 JDK 时,报错通常不会直接告诉你这一点。
启动数据库容器
书中的 SQL 和 JDBC 示例默认连接下面这个容器:
docker run -d --rm --name libraryd-pg \
-e POSTGRES_DB=libraryd \
-e POSTGRES_USER=libraryd \
-e POSTGRES_PASSWORD=libraryd \
-p 127.0.0.1:5432:5432 \
postgres:17-alpine
等待数据库就绪:
until docker exec libraryd-pg pg_isready -U libraryd -d libraryd >/dev/null 2>&1; do
sleep 1
done
连接参数:
LIBRARYD_DB_URL=jdbc:postgresql://localhost:5432/libraryd
LIBRARYD_DB_USER=libraryd
LIBRARYD_DB_PASSWORD=libraryd
如果本机 5432 已被占用,把 -p 改成 127.0.0.1:55432:5432,同时把 URL 里的端口改成 55432。全书示例默认 5432;遇到端口冲突时,只改端口,不要改库名和用户名。
用完可以停止容器:
docker stop libraryd-pg
--rm 会在容器停止后删除它,数据也随之消失。第 4 章之后如果你想保留数据,把 --rm 去掉,并给容器一个固定名字。
代码约定
包名。 全书使用 com.plume.library。模块目录名带 libraryd- 前缀,包名不带:libraryd-persistence 模块里的代码仍然在 com.plume.library.persistence 下。
模块与依赖方向。 domain 不依赖其他模块;persistence 和 web 依赖 domain;app 依赖全部。代码片段如果只展示一个类,可能省略 import;完整示例会写全。
类名。 领域对象用名词(Book、Member、Loan),服务用 XxxService,仓储用 XxxRepository,异常用 XxxException。接口与实现分开:BookRepository 是接口,JdbcBookRepository 是实现。
代码块。 完整 Java 代码标 java;SQL 标 sql;命令行标 bash;终端输出标 text;pom.xml 标 xml;配置文件标 yaml 或 properties;Dockerfile 标 dockerfile。代码块里的 ... 表示省略,直接复制会编译失败。
输出。 代码块之后紧跟的 text 块是真实输出;为说明结构而简化的会标「示意」。HTTP 示例会给出完整的请求命令、状态码和响应体;只给字段说明而不给 curl 命令的,表示响应体经过省略。
容器。 每节需要的容器会在开头给出启动命令;同一章内复用同一个容器,不重复创建。Testcontainers 会自动管理自己的容器,不需要手动启动。
版本标注。 依赖版本以父 POM 为准;正文提到版本时,是在解释「为什么锁这个版本」,不是让你在子模块里再写一遍。
怎么验证代码
四个层次,按需要选择。
单文件:javac
适合一个完整类:
mvn -q -DskipTests package
mvn -q -pl libraryd-web dependency:build-classpath -Dmdep.outputFile=/tmp/libraryd-cp.txt
javac -cp "libraryd-web/target/classes:$(cat /tmp/libraryd-cp.txt)" -d /tmp/java_check Book.java
书中的类通常依赖领域类型或第三方库,直接用 javac 时需要把工程的 classpath 带上。本书不附带可下载的源码包,你需要按章节自己敲;每节代码足以拼出对应阶段的工程。如果只想验证单个类,把它放进对应模块的 src/main/java 下,运行:
mvn -q -pl libraryd-domain -am -DskipTests compile
片段:jshell
适合验证一两行表达式:
jshell
jshell> List.of(3, 1, 2).stream().sorted().toList()
$1 ==> [1, 2, 3]
jshell 不适合验证包结构、模块依赖和 Spring 之外的容器装配。
工程:mvn test
适合验证当前章节的完整工程:
mvn -q test
测试需要 Docker 时(第 15 章),Testcontainers 会自动拉取镜像并启动容器。第一次运行会下载依赖和镜像,耗时较长;之后使用本地缓存。
服务:curl
适合验证 HTTP 契约:
curl -i -X POST http://localhost:8080/api/books \
-H 'Content-Type: application/json' \
-d '{"isbn":"978-7-115-54736-1","title":"Java 编程实战","author":"Leeting Yan","year":2026}'
-i 会显示状态码和响应头。排查契约问题时,状态码、Content-Type 和响应体要一起看。
三种阅读路径
完整实战(约 6 周)。 按 1→16 章顺序读,每周 2–3 章,每章代码跑通再往下。第 6 周结束时,你应该有一个能 docker run 的 libraryd。
服务端速成(约 3 周)。 第 1 章读模块拆分与依赖治理,第 3–8 章按顺序读,第 9–11 章只读虚拟线程和定时任务,第 12–13 章读日志与指标,第 15–16 章读 Testcontainers 与容器化。
按问题查(按需)。 直接看目录篇的章节表。高频入口:连接池看 3.2,索引看 4.2,并发借阅看 5.3,错误契约看 8.2,线程池看 9.1,指标看 13.1,镜像看 16.2。
关于版本与错误
本书以 JDK 25 LTS、Maven 3.9.12、PostgreSQL 17、Javalin 7.2.4 为主线。所有依赖版本在父 POM 统一锁定,附录 B 给出选型理由。
如果你在 JDK 21 上运行,大部分代码仍然成立;虚拟线程相关章节会标注 21 与 25 的差异。PostgreSQL 16 与 17 在本卷涉及的 SQL 上行为基本一致,但 EXPLAIN 输出格式可能略有不同。
书中难免有错误。发现代码跑不通时,按这个顺序排查:
- 确认
java -version、mvn -version与父 POM 的release一致。 - 确认数据库容器已启动,端口和库名与配置一致。
- 看本节末尾的「常见错误」和附录 C。
- 用
mvn -q -pl <模块> -am test单独跑失败模块,缩小范围。 - 还不行,就把完整报错、SQL 和最小复现代码记下来,再查官方文档。
Java 的编译错误通常很具体;服务端问题则更多依赖日志和状态码。先确认失败发生在哪一层——编译、启动、请求处理、数据库还是容器网络——比凭感觉改配置快得多。
从哪开始
如果你已经装好 JDK 25、Maven 和 Docker,直接跳到第 1 章;如果还没装,先按上面的环境清单做完。第 1 章不讲 HTTP,也不讲数据库,只做一件事:把卷一那个能跑的单模块程序,拆成边界清楚的五个模块。
准备好了,就从 1.1 从单模块到多模块 开始。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。