《Java 编程实战》前言

交代本书的读者对象、前置知识与六部分结构,列出 JDK 25、Maven、Docker 与 PostgreSQL 17 的环境清单和真实版本输出,说明代码、输出、容器与命令的书写约定,以及三种阅读路径、验证代码的四个层次与版本不一致时的排查顺序。

这本书写给谁

这本书写给三类人。

第一类:刚读完《Java 编程入门》,想接着做项目。 你会写类、集合、Stream、异常和 JUnit,也能用 Maven 打出一个可执行 jar,但还没有把程序接到数据库、暴露成 HTTP 服务、部署成容器的经验。这本书按顺序补上这些。

第二类:会 Java,但没做过服务端。 你可能写过桌面工具、批处理脚本或 Android 应用,知道 Java 语法,但对连接池、事务、索引、线程池、可观测性这些服务端概念只有零散印象。书里不会重新讲语法,会从工程问题切入。

第三类:做过 Spring Boot,想看清框架替你做了什么。 你能用 @Transactional、@Valid、Actuator 把服务搭起来,但遇到「事务为什么没回滚」「校验为什么没触发」「指标为什么没有」时说不清原因。这本书用 Javalin 和手写装配把同样的位置实现一遍,附录 D 再对照 Spring Boot。

如果你还不会 Java 的基础语法,建议先读卷一。卷二默认你能读懂 record、泛型、Lambda、Stream 和异常体系,不会再解释这些。

前置知识

除了 Java 语言本身,还需要三件事:

  1. 会用 Maven。 知道 pom.xml、依赖作用域、mvn test 和 mvn package 的区别。第 1 章会讲多模块,但不从零讲 Maven。
  2. 写过基础 SQL。 知道 select、insert、update、delete、join 和 where。索引、执行计划和事务会在第 4、5 章展开。
  3. 会用命令行和 Docker。 知道 cd、环境变量、curl,能运行 docker run 并看懂端口映射。数据库实验都在容器里做,不要求本机安装 PostgreSQL。

不需要提前会 Javalin、Jackson、HikariCP 或 Testcontainers。这些库会在用到的那一章从零开始讲。

本书结构

全书 55 篇,分六个部分:

部分章节解决的问题
一、工程基座1–2多模块、依赖治理、静态分析与质量门禁
二、数据访问3–6JDBC、连接池、schema、索引、事务、JSON
三、HTTP 服务7–8路由、中间件、校验、错误契约、优雅停机
四、并发与异步9–11线程池、虚拟线程、CompletableFuture、定时任务
五、可观测性与缓存12–14日志、指标、追踪、健康检查、Caffeine、Redis
六、测试与交付15–16Testcontainers、端到端测试、镜像、发布与回滚

章节之间有依赖。第 3 章的仓储依赖第 1 章的模块边界,第 5 章的事务依赖第 3 章的连接池,第 13 章的指标依赖第 7 章的中间件。跳章可以,但不要跳过第 3、5、7 章直接看第 15 章。

环境清单

本书的写作与验证环境:

项版本说明
操作系统macOS 26.3(arm64)Linux 命令基本一致;Windows 需替换路径分隔符
JDKTemurin 25.0.5+8(LTS)JAVA_HOME=~/.jdks/jdk-25.0.5+8/Contents/Home
Maven3.9.12mvn -version 的 Java 版本应为 25.0.5
Docker29.7.2(客户端)用于 PostgreSQL、Redis 与 Testcontainers
PostgreSQL17.11(容器 postgres:17-alpine)本机不要求安装数据库
终端zshbash 也可;Windows 用 PowerShell 时注意引号
编码UTF-8JDK 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 输出格式可能略有不同。

书中难免有错误。发现代码跑不通时,按这个顺序排查:

  1. 确认 java -version、mvn -version 与父 POM 的 release 一致。
  2. 确认数据库容器已启动,端口和库名与配置一致。
  3. 看本节末尾的「常见错误」和附录 C。
  4. 用 mvn -q -pl <模块> -am test 单独跑失败模块,缩小范围。
  5. 还不行,就把完整报错、SQL 和最小复现代码记下来,再查官方文档。

Java 的编译错误通常很具体;服务端问题则更多依赖日志和状态码。先确认失败发生在哪一层——编译、启动、请求处理、数据库还是容器网络——比凭感觉改配置快得多。

从哪开始

如果你已经装好 JDK 25、Maven 和 Docker,直接跳到第 1 章;如果还没装,先按上面的环境清单做完。第 1 章不讲 HTTP,也不讲数据库,只做一件事:把卷一那个能跑的单模块程序,拆成边界清楚的五个模块。

准备好了,就从 1.1 从单模块到多模块 开始。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. 《Netty 高性能网络编程》15.3 linkd-v2 验收与复盘
  2. 《Netty 高性能网络编程》15.2 限流、超时与降级
  3. 《Netty 高性能网络编程》15.1 网关路由与转发