Lombok 拾遗
Created|Updated|Java
|Word Count:43|Reading Time:1mins|Post Views:
sneakyThrow
1 | |
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2026-10-04
Java常用类库-E08-MapStruct与Lombok的生成代码契约
删除手写代码之前先保留行为契约 商品输入对象需要转换成展示对象,还需要支持更新已有对象。MapStruct 可以生成字段映射,Lombok 可以生成访问器、builder 和相等方法。代码行数减少之后,null、集合引用和 hashCode 行为仍然存在;如果不检查生成结果,就可能把原本看得见的决策变成构建过程中隐含的默认值。 本篇使用独立 Maven 模块,实际运行 MapStruct 1.6.3 与 Lombok 1.18.42,并显式加入 lombok-mapstruct-binding 0.2.0。固定源码分别为 b4e25e49deae707b50ce061172e114292b414a23 与 2031eb0880942b5f0b7281580f6e877a3e87279a。所有应用源码保持 Java 8,在 JDK 8 和 JDK 21 分别 clean verify,没有用已经生成的 class 代替处理器执行。 完整项目见 下载处理器实验工程,测试见 ProcessorContractTest.java,生成映射见 ProductMapperImpl.java,...
2026-10-04
深入 Play E04:Pekko HTTP 与 Netty,相同 Controller 的传输边界
两份字节相同的 Controller、路由和配置,都能正确解析 JSON、传输数据和完成 WebSocket 回声。向正在处理请求的生产进程发送 SIGTERM 后,结果发生了分叉:Pekko HTTP 返回完整的 200 completed,Netty 客户端收到 RemoteDisconnected。两边的业务回调和 stop hook 却都执行了。 Play 的应用层抽象使多数业务代码可以跨后端复用,连接关闭、协议错误和终止阶段仍由具体传输实现参与决定。本章固定版本,用相同输入、真实 TCP 连接和进程信号比较这些边界。 固定构件,确认真正运行的后端 下载两套服务器后端工程与实验记录,核对SHA256SUMS。解压后的 play-electives/e04-backends 包含Pekko与Netty应用;接入后重跑4项JUnit、两套stage与36项网络观察,20个应用class与生产jar字节一致,见 evidence/e04/integration。WebSocket协议错误与在途停机差异均保留。 实验固定 Play 3.0.6、Scala 2.13.15、sbt...
2026-10-04
深入 Spring 33:缓存键、并发加载与事务回滚
数据库回滚,缓存为什么还保留新值 一次操作写入数据库,再通过 @CachePut 更新价格缓存,最后把事务标记为 rollback-only。独立连接确认数据库里没有新记录,缓存里却能读到 uncommitted。这个结果不需要框架出错:普通内存缓存与 JDBC 事务管理器没有共同的提交协议。 缓存一致性至少涉及键空间、加载并发和提交边界。代理命中只能说明某次调用找到了缓存条目,不能证明条目仍然新鲜,也不能证明它来自已经提交的数据库状态。 实验 blog.spring.Chapter33 固定 Spring Framework 6.2.11、JDK 21、ConcurrentMapCacheManager,数据库使用 PostgreSQL 18.0。所有缓存结论都限定在这个 provider 和单 JVM 内;没有用本地 sync=true 推导 Redis 集群的行为。 CacheInterceptor 处理调用,provider 保存数据 @EnableCaching 注册缓存 Advisor,CacheInterceptor 把代理调用委托给 CacheAspectSup...

2026-10-04
设计模式 27:谁能读取延迟加载的库存
库存查询的构建成本较高;访客又不允许查询。旧对象一创建就调用加载器,随后查询时才核对身份,结果是未授权请求已经触发了一次昂贵加载。能否做到先拒绝、授权后首次使用才加载,并让后续查询复用已加载对象? 控制访问与加载时机 Before 在构造器里调用 loader.get();反例断言访客随后被拒绝,加载次数却已经是 1。After 实现与真实 Inventory 相同的 available(sku) 接口,在构造时绑定本章教学角色。调用入口先检查是否为 stock-reader,然后首次使用加载对象、再次使用复用;测试分别断言未授权 0 次加载、授权两次读取只加载 1 次、加载器的异常向外传播。Alternative 用一个普通函数先查角色再加载,适用于只查一次、无需复用实例的场合。 12345public int available(String sku) { authorize(role); if (loaded == null) loaded = loader.get(); return loaded.available(sku);} 此...
2026-10-04
深入 Spring 22:回滚规则、异常捕获与rollback-only
抛出异常与数据库回滚不是同一个结果 事务方法插入一行后抛出 checked exception,调用方捕获到异常,数据库却保留了那一行。另一个事务方法捕获内部异常并正常返回,调用方反而收到 UnexpectedRollbackException,数据库没有留下记录。两个结果都符合 Spring 的默认行为,它们分别涉及回滚规则与共享事务的 rollback-only 状态。 默认规则把 RuntimeException 和 Error 视为回滚原因,普通 checked exception 不触发回滚。这个规则处理的是穿过事务拦截边界的异常;在方法内部已捕获的异常不会自动传递给拦截器。同时,方法正常返回也不能清除已存在的 rollback-only 标志。默认事务属性源码 本文固定 Spring Framework 6.2.11、JDK 21,源码提交 4c134254642d88e058aa004bdaf44168e1be7bb2。PostgreSQL 18.0、pgjdbc 42.7.7、HikariCP 5.0.1 提供真实数据库与连接池。每个场景都通过独立连接读取已提交记...
2026-05-21
回到工程:计算理论怎样改变写代码的眼光
这个系列从《计算的本质》重新出发,用 Python 重写核心实验,再把每个模型映射到 Java 程序员熟悉的工程结构。一路走下来,主题并不是记住更多术语,而是换一种方式观察程序。 程序可以是语法树,执行可以是规约,协议可以是自动机,嵌套可以靠栈,通用计算可以由解释器承载,分析工具也可以承认不精确并保持有用。 本文不再引入新模型,只把前面十几篇文章收束成一张工程地图。 概念地图 先把系列里最重要的模型压成一段可运行的概念地图。 12345678910concept_map = [ ("AST / 语义", "解释器、DSL、规则执行"), ("DFA / NFA / 正则", "协议状态、校验器、词法分析"), ("PDA / 栈", "parser、嵌套结构、调用栈"), ("图灵机 / 通用性", "VM、脚本引擎、程序作为数据"), ("停机问题 / 抽象解释", &...
Contents
