<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SpringBoot4 - 标签 | 飞污熊小站</title><link>https://xiongneng.me/tags/springboot4/</link><description>飞污熊小站</description><generator>Hugo 0.166.0 &amp; FixIt v0.4.6-20260512073637-464c4659</generator><language>zh-CN</language><managingEditor>yidao620@163.com (XiongNeng)</managingEditor><webMaster>yidao620@163.com (XiongNeng)</webMaster><copyright>XiongNeng</copyright><lastBuildDate>Fri, 25 Sep 2026 02:16:47 +0000</lastBuildDate><atom:link href="https://xiongneng.me/tags/springboot4/index.xml" rel="self" type="application/rss+xml"/><item><title>SpringBoot4系列18 - 使用Spring Security 7权限管理</title><link>https://xiongneng.me/posts/java/springboot/sb4-security/</link><pubDate>Sat, 24 Oct 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-security/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;运营后台的权限需求我接到过不止一次：客服查订单，管理员取消订单、翻审计。早年我偷懒，在每个接口开头手写身份判断，&lt;code&gt;if (!currentUser().isAdmin())&lt;/code&gt; 复制到十几个方法里，后来加一个角色要全局搜一遍 if，说实话我自己都说不清某个接口到底谁能调。身份认证与授权是「所有请求进业务之前都要过一遍」的横切关卡，这类活儿交给 Spring Security 的过滤器链正合适，我在这篇里把整套方案在 Spring Boot 4.1.1 加 Spring Security 7.1.1 上完整落了一遍。&lt;/p&gt;</description></item><item><title>SpringBoot4系列17 - 自己写Starter</title><link>https://xiongneng.me/posts/java/springboot/sb4-starter/</link><pubDate>Fri, 23 Oct 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-starter/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上个月我干了一件特别没有技术含量的事：把订单服务、库存服务、售后服务三个仓库里各一份的短消息通知代码翻出来对了一遍。发送逻辑差不多，重试次数是三个魔法数字，渠道配置三个 yml 各写各的。产品说把重试从 2 次调成 3 次，我改一处配置的活儿硬是变成了改三个仓库、发三次版、回归三遍。这类代码不属于任何一个业务，属于「所有服务都要用一份配置管理起来」的公共设施，starter 就是为它准备的封装形态。&lt;/p&gt;</description></item><item><title>SpringBoot4系列16 - 使用AOP</title><link>https://xiongneng.me/posts/java/springboot/sb4-aop/</link><pubDate>Thu, 22 Oct 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-aop/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;我给订单服务定过一个小目标：每个接口统计耗时、关键操作留审计、下单支付防重复提交。这三件事都不难，难在它们跟业务一点关系都没有。没有切面的写法是把它们复制进每个方法：&lt;code&gt;System.currentTimeMillis()&lt;/code&gt; 抬头低头各一次，审计字段在返回前手动塞库，幂等靠前端按钮置灰。我见过三个月后的下场：没人说得清哪些接口漏了计时，审计表里缺哪天的行，重复提交打穿库存的客诉截图还挂在群里。这三件事的共性是它们不属于任何业务方法，属于「所有方法都要过一遍」的横切关注点，切面正是为这类代码准备的。&lt;/p&gt;</description></item><item><title>SpringBoot4系列15 - 集成gRPC服务</title><link>https://xiongneng.me/posts/java/springboot/sb4-grpc/</link><pubDate>Wed, 21 Oct 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-grpc/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;先交代一个我亲身踩过的坑：订单服务每次调用物流服务，双方都在赌对方没改接口。HTTP 面上跑的是 JSON：请求字段靠字符串拼，响应字段靠手抄文档。物流团队把响应里的 &lt;code&gt;waybillNo&lt;/code&gt; 改名成 &lt;code&gt;shipmentId&lt;/code&gt;，旧字段悄悄删掉，订单服务的解析代码拿到 &lt;code&gt;null&lt;/code&gt; 照常往下走，三天后客服才发现运单号全空。改字段这种事在强类型世界有编译器拦着，在 JSON 世界只有运行时的 &lt;code&gt;null&lt;/code&gt; 和日志里一条没人看的 WARN。那次之后我就认准了一件事：跨服务的字段契约不能靠人肉维护。&lt;/p&gt;</description></item><item><title>SpringBoot4系列14 - 使用声明式HTTP客户端RestClient</title><link>https://xiongneng.me/posts/java/springboot/sb4-restclient/</link><pubDate>Tue, 20 Oct 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-restclient/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;订单服务刚上线那阵子，我对它发出去的两个上游调用心里一直没底：风控服务在下单前校验这笔单子有没有问题，物流服务在支付后生成运单。第一版实现里，这两个调用散落在 Service 的各个角落：URL 字符串硬编码在方法体里，参数拼接靠手写格式化，响应解析各写一套，超时一个都没配。后来风控服务某次发布期 503 了半小时，订单服务整段跟着不可用，我排查时发现三处调用点了三套错误处理，其中一处直接把异常吞了，单子就这么无声无息地放过去了。&lt;/p&gt;</description></item><item><title>SpringBoot4系列13 - 使用WebSocket实时通信</title><link>https://xiongneng.me/posts/java/springboot/sb4-websocket/</link><pubDate>Tue, 13 Oct 2026 20:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-websocket/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;运营后台的「新订单监控」页面是我先用轮询撑起来的：前端每 3 秒发一次 &lt;code&gt;GET /api/orders?since=…&lt;/code&gt;，几百个页面同时开着，一秒钟就是上百个请求，其中九成以上查回来的是空数组。高峰期轮询请求和正常下单请求挤在同一条队列里，接口响应从 40 毫秒涨到 1 秒开外，运营跑来找我反馈「页面刷新慢」，我打开数据库慢查询日志，里面躺着一排一模一样的查询，那一刻我就知道该换方案了。&lt;/p&gt;</description></item><item><title>SpringBoot4系列12 - 使用异步任务与线程池</title><link>https://xiongneng.me/posts/java/springboot/sb4-async/</link><pubDate>Mon, 12 Oct 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-async/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;前阵子我盯着一个下单接口，落库本身很快，麻烦都在落库之后：给客户发短信通知要 600 毫秒，积分入账要 700 毫秒，报表聚合要 800 毫秒。原来的写法是三件事按顺序排在一个方法里，我拿 curl 压了一把，接口响应 2155 毫秒，高峰期每个请求都把 HTTP 线程占住两秒多，吞吐量被这几件慢活按在地上。&lt;/p&gt;</description></item><item><title>SpringBoot4系列11 - 使用定时任务Schedule</title><link>https://xiongneng.me/posts/java/springboot/sb4-schedule/</link><pubDate>Sun, 11 Oct 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-schedule/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一章的 Spring Batch 解决的是「算得完」，这一篇解决「准时跑」。场景还是订单业务：每天凌晨扫对账文件，每隔几秒把超时未支付的订单取消掉，固定节拍刷新一次报表快照。这类活的共同点是间隔固定、单次很轻、一个都不能长期缺席。&lt;/p&gt;</description></item><item><title>SpringBoot4系列10 - 使用批处理Spring Batch</title><link>https://xiongneng.me/posts/java/springboot/sb4-batch/</link><pubDate>Sat, 10 Oct 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-batch/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一章的 RabbitMQ 解决的是「通知得可靠」，这一章解决「算得完」。场景还是订单：每天凌晨把当天的对账文件倒进数据库，月底把全量用户跑一遍账单，每个季度把失效数据归档。这类活的共同点是数据量大、允许延迟、绝不允许算一半。你可以接受结果晚几个小时出来，但不能接受一个算了一半的结果被当成完整结果用。&lt;/p&gt;</description></item><item><title>SpringBoot4系列09 - 使用消息队列RabbitMQ</title><link>https://xiongneng.me/posts/java/springboot/sb4-rabbitmq/</link><pubDate>Wed, 07 Oct 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-rabbitmq/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一篇讲缓存，结尾留了个尾巴：缓存解决的是「读得快」，系统里另一半问题「通知得可靠」还空着，这一篇来补。场景还是订单。订单支付成功之后要发短信、要推邮件、要给积分系统记账，这几件事没有一件是下单主链路必须等着的，也没有一件是挂了能装作没看见的。&lt;/p&gt;</description></item><item><title>SpringBoot4系列08 - 使用缓存</title><link>https://xiongneng.me/posts/java/springboot/sb4-cache/</link><pubDate>Wed, 30 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-cache/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一篇讲 Redis 收尾的时候留了句尾巴：RedisTemplate 那套是「自己动手」的用法，键怎么起、TTL 给多少、什么时候删，全是我自己说了算。自己动手自由，可这些手工操作散落在业务代码各处，时间一长就没人说得清全貌了。这一篇讲另一条路，Spring 从 3.1 就备好的声明式缓存：方法上贴个注解，命中不进方法体，未命中执行完自动写缓存，删除也是注解一句话的事。&lt;/p&gt;</description></item><item><title>SpringBoot4系列07 - Redis数据库</title><link>https://xiongneng.me/posts/java/springboot/sb4-redis/</link><pubDate>Wed, 23 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-redis/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一篇结尾留了个话头，说从这一篇开始进 &lt;code&gt;P-2&lt;/code&gt;，第一个要面对的问题是「Redis 的操作什么时候算成功，跟本地事务没有半点关系」。&lt;/p&gt;&#10;&lt;p&gt;这一篇就是。&lt;/p&gt;&#10;&lt;p&gt;Redis 不太愿意把自己叫数据库，官方给它的定位是数据结构服务器。String、Hash、List、Set、Sorted Set 这些结构在它这里是一等公民，每个命令都是原子操作，进去了就出结果，没有一半提交一半回滚这回事。&lt;/p&gt;</description></item><item><title>SpringBoot4系列06 - 声明式事务</title><link>https://xiongneng.me/posts/java/springboot/sb4-transaction/</link><pubDate>Tue, 22 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-transaction/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;第五篇收尾时留了个话头：一个事务管理器身上，还有哪些东西是配置不出来的。这一篇回答它。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;@Transactional&lt;/code&gt; 是 Spring 里最像「不用学」的注解：加一行，方法就进事务了。但它有个脾气：&lt;strong&gt;用对的时候什么都不用知道，用错了它不告诉你。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;最典型的翻车现场：接口返回 422，异常栈打在日志里，调用方按失败处理。然后查库，钱已经扣了。没有报错，没有 WARN，日志上还写着「Initiating transaction commit」，事务管理器认为一切正常，按照默认规则该提交。&lt;/p&gt;</description></item><item><title>SpringBoot4系列05 - 多数据源配置</title><link>https://xiongneng.me/posts/java/springboot/sb4-multisource/</link><pubDate>Mon, 21 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-multisource/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;第二篇那个订单工程，数据源是启动时自动配好的那一个：yml 里写一句 &lt;code&gt;spring.datasource.url&lt;/code&gt;，Boot 就照着它建好 &lt;code&gt;HikariDataSource&lt;/code&gt;、&lt;code&gt;SqlSessionFactory&lt;/code&gt; 和事务管理器，一行配置类都不用写。&lt;/p&gt;</description></item><item><title>SpringBoot4系列30 - 用Spring AI把业务接口暴露成MCP工具</title><link>https://xiongneng.me/posts/java/springboot/sb4-ai-mcp/</link><pubDate>Mon, 21 Sep 2026 12:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-ai-mcp/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;客服后台常有这类请求：「ORD-1001 到哪一步了」「客户 C-001 最近买了什么」「这周下了多少单」。对应的查询接口系统里都有，但入口藏在运营后台的几个页面里，客服要在页面之间跳转、记订单号、再拼出答案。说实话，我一开始想的是给客服再做一个问答页面，后来发现大型语言模型宿主（Claude Desktop、Cursor、Claude Code）已经能理解这类自然语言问题，也能在理解之后调用外部函数，缺的只是一个标准协议，把订单系统的查询方法递到模型手里。Model Context Protocol（MCP）就是这个协议。&lt;/p&gt;</description></item><item><title>SpringBoot4系列22 - 使用API版本管理</title><link>https://xiongneng.me/posts/java/springboot/sb4-apiversion/</link><pubDate>Mon, 21 Sep 2026 10:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-apiversion/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;先讲一段我自己的亲身经历。订单服务跑到第二年，产品要在新版 App 里把金额拆开摆：商品金额、折扣、运费各自一行。我把 &lt;code&gt;/api/orders/{id}&lt;/code&gt; 的响应体重构了一遍，customerName 与 customerPhone 聚成 customer 对象，金额拆成 items 数组加 amount 子结构，自测没问题就发了版。上线十分钟，财务的对账系统报警：它按字段平铺解析订单 JSON，customer 对象它不认识，整批对账任务全挂。回滚、发版、写死一套字段映射兼容代码，前前后后折腾了我一周。&lt;/p&gt;</description></item><item><title>SpringBoot4系列21 - 测试体系JUnit 6与Testcontainers</title><link>https://xiongneng.me/posts/java/springboot/sb4-testing/</link><pubDate>Mon, 21 Sep 2026 00:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-testing/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;先说一个我印象很深的场景：一家公司的订单服务上线两年，测试全靠打开浏览器手工点接口。下单、支付、查列表、删订单，一轮点下来四十分钟，改了支付逻辑还得把查询和删除再点一遍。一次完整回归半天起步，改一行代码不敢当天上线，攒到周五集中发布，发布窗口里谁也说不准哪条旧逻辑会被带崩。&lt;/p&gt;</description></item><item><title>SpringBoot4系列29 - 服务端图表数据接口与PNG导出</title><link>https://xiongneng.me/posts/java/springboot/sb4-echarts/</link><pubDate>Sun, 20 Sep 2026 23:59:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-echarts/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;运营平台的报表需求里有一类固定动作：每天早上把昨天的订单统计图发到工作群。图要有、消息要准时，还要在群里直接能看，转发链接与打开网页都嫌多余。我最后选的做法，是服务端定时把图表渲染成 PNG，交给消息通道发出去。浏览器端 ECharts 画图没问题，但 PNG 要在服务端出，渲染这件事就得由后端想办法。&lt;/p&gt;</description></item><item><title>SpringBoot4系列20 - 使用OpenAPI 3.1接口文档</title><link>https://xiongneng.me/posts/java/springboot/sb4-openapi/</link><pubDate>Sun, 20 Sep 2026 23:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-openapi/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;一家公司的订单服务有三种消费方：小程序前端、运营后台、一家做对账的合作方。接口怎么调、字段什么含义，靠群里发消息同步，消息刷走一次，联调就对不上一次。我把字段说明放进共享文档试过一版，代码改了没人记得改文档，三个月之后那份文档没有一行敢信。前端问我「金额是元还是分」，答案明明就在代码里，却不在任何一份我能拿得出手的文档里。&lt;/p&gt;</description></item><item><title>SpringBoot4系列28 - 集成Thymeleaf服务端渲染</title><link>https://xiongneng.me/posts/java/springboot/sb4-thymeleaf/</link><pubDate>Sun, 20 Sep 2026 22:32:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-thymeleaf/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;公司内部的运营后台十有八九长一个样：商品录入、审批列表、参数配置页，页面结构简单，交互以表单提交加刷新列表为主。这种页面用前后端分离去做，我要维护两套代码、一条接口约定，还得排一次联调，投入产出比实在不划算。说实话，把页面拼装放回服务端，一个工程、一套部署就能交付，这类内部工具我一律上 Thymeleaf。Spring 官方对模板技术的推荐位很多年前就给了它：自然的 HTML 原型（直接双击就能打开）、与 Spring MVC 的表单绑定、开箱即用的 Bean Validation 错误回显，都是我需要的东西。&lt;/p&gt;</description></item><item><title>SpringBoot4系列27 - 使用虚拟线程提升吞吐</title><link>https://xiongneng.me/posts/java/springboot/sb4-virtualthreads/</link><pubDate>Sun, 20 Sep 2026 22:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-virtualthreads/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;先摆一下我遇到的问题。订单详情页有一个聚合接口：请求进来后要串行调库存、定价、物流三个下游，每次调用 200ms，接口总耗时 600ms。大促峰值要撑 3000 QPS，按排队论算容量，需要的并发处理线程数是 3000 × 0.6s = 1800 个。Tomcat 的请求线程池默认上限 200，吞吐天花板是 200 / 0.6s ≈ 333 req/s，距离目标差 5 倍。把线程池调到 2000 也能算出差不多的容量，但每个平台线程预分配 1MB 栈内存，2000 个线程就是 2GB 的固定开销，加上上下文切换和调度成本，这条路我在评审里见过太多回，基本都走到头了。&lt;/p&gt;</description></item><item><title>SpringBoot4系列04 - 集成MongoDB</title><link>https://xiongneng.me/posts/java/springboot/sb4-mongodb/</link><pubDate>Sun, 20 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-mongodb/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一篇结尾我留过一个判断：&lt;code&gt;OrderRepository&lt;/code&gt; 这个接口再换一次实现，如果还那么顺，分层这件事就算做对了。&lt;/p&gt;&#10;&lt;p&gt;这次换 MongoDB。&lt;/p&gt;&#10;&lt;p&gt;先把我的结论放这儿：接口契约又是一个字没改，Controller、DTO、状态机、错误响应的形状全部原样，连 &lt;code&gt;/api/orders/{id}&lt;/code&gt; 路径都一样。唯一看得见的变化是主键从自增数字变成了 24 位十六进制的 ObjectId。&lt;/p&gt;</description></item><item><title>SpringBoot4系列19 - 使用OAuth2与JWT接口认证</title><link>https://xiongneng.me/posts/java/springboot/sb4-oauth2/</link><pubDate>Sun, 20 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-oauth2/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;一家公司里，订单服务背后站着三个内部系统：物流系统查订单安排发货，报表系统拉数据做统计，对账系统定时核对金额。最早的接法是三方约定一个共享密码，每个系统调接口时都带上它。我接手这种系统时最怕的就是换密码：三个系统的配置、两份脚本、一个定时任务挨个改，改漏一个就出一批 401 告警。共享密码的要害在于「一台机器一个身份、一种权限」没有任何地方可以表达，全部调用方共用同一份凭据。OAuth2 的 client_credentials 授权模式解决的正是这件事：每个系统一个 client，一个 client 一组 scope，凭据过期自动换，接口侧只认 JWT 令牌本身。&lt;/p&gt;</description></item><item><title>SpringBoot4系列26 - 使用GraalVM原生镜像与AOT</title><link>https://xiongneng.me/posts/java/springboot/sb4-native/</link><pubDate>Sun, 20 Sep 2026 21:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-native/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;前段时间盯着大促扩容看了一个问题：流量上来，Kubernetes 给订单服务一口气扩 10 个副本，结果新 Pod 得等 JVM 把 8000 多个类加载完、几十个自动配置类解析完才能接流量，就绪探针配 60 秒都不保险。缩容再扩容这么来回几次，冷启动时间就是实打实的容量成本，要是放在 Serverless 场景按毫秒计费，这笔开销甚至能决定方案能不能用。&lt;/p&gt;</description></item><item><title>SpringBoot4系列25 - 使用内置弹性重试与并发限制</title><link>https://xiongneng.me/posts/java/springboot/sb4-resilience/</link><pubDate>Sun, 20 Sep 2026 20:40:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-resilience/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;前段时间我给支付服务对接下游通道，通道偶尔抖一下：前两秒请求全超时，第三秒自己恢复。老处理办法是引 spring-retry 或 Resilience4j，加依赖、加 @EnableRetry、按各自词表写注解，一套下来 POM 多两组坐标，依赖树多两层传递。这次我把 Spring Framework 7 收进框架本体的方案完整跑了一遍：@Retryable 和 @ConcurrencyLimit 两个注解加一个 @EnableResilientMethods 开关，重试与并发限制开箱即用，spring-retry 进入维护模式，Resilience4j 的注解体系在纯重试场景也省了。&lt;/p&gt;</description></item><item><title>SpringBoot4系列24 - 使用Actuator与OpenTelemetry可观测性</title><link>https://xiongneng.me/posts/java/springboot/sb4-observability/</link><pubDate>Sun, 20 Sep 2026 19:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-observability/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上个月支付网关出了一次故障，客服那边的投诉先进来，我这边才反应过去翻日志。日志有，但散在四个服务实例里，想回答「昨晚十点支付接口慢在哪」，我得先找到慢的判断依据，再去四个实例里捞请求日志，最后把两次跨服务调用的日志按请求对上号。这三件事分别对应指标、链路、日志，工程上叫可观测性三件套。复盘的时候我意识到，排障有个更早的阶段：问题还没发生时，系统就该把三类信号持续吐出去，指标给告警提供阈值，链路给定位提供调用路径，日志给复盘提供细节。&lt;/p&gt;</description></item><item><title>SpringBoot4系列23 - 使用Jackson 3与空安全</title><link>https://xiongneng.me/posts/java/springboot/sb4-jackson3/</link><pubDate>Sun, 20 Sep 2026 16:30:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-jackson3/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;前段时间我帮订单服务做过一次对账排查：财务那边的解析脚本按「字段有值才算有效记录」的口径读订单 JSON。游客单没留电话、没用优惠券、没填备注，响应体里这些字段带着 null 原样输出，对账脚本把整批订单判成无效数据，夜里重跑了三次，我第二天早上才看到告警。另一件事更隐蔽：金额字段 discountCents 在下单链路里偶尔是 null，对账方拿到 null 按数值 0 参与汇总，月初的折扣报表少算了两万块，排查的时候我才搞明白，null 与 0 在他们的口径里是两个东西，这么混着用迟早闹笑话。&lt;/p&gt;</description></item><item><title>SpringBoot4系列03 - 集成Spring Data JPA与Hibernate 7</title><link>https://xiongneng.me/posts/java/springboot/sb4-jpa/</link><pubDate>Sat, 19 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-jpa/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;上一篇结尾我留了个约定：&lt;code&gt;OrderRepository&lt;/code&gt; 还要再换一次实现，如果接口还撑得住，分层就算做对了。这篇换 Spring Data JPA，我来兑现这句话。&lt;/p&gt;&#10;&lt;p&gt;结论先放这儿：接口契约一个字没改，Controller、DTO、状态机、错误响应全部原样。但说实话，这是系列里坑最多的一篇，比前两篇加起来还多，而且大多不在「报错」，在「悄悄按另一套规则跑」，等你发现时数据已经不对了。&lt;/p&gt;</description></item><item><title>SpringBoot4系列02 - 集成MyBatis-Plus</title><link>https://xiongneng.me/posts/java/springboot/sb4-mybatis/</link><pubDate>Fri, 18 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-mybatis/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;第 1 篇收尾的时候我留了一句话：&lt;code&gt;OrderRepository&lt;/code&gt; 接口先空着，MyBatis、JPA、MongoDB 三篇各给一个实现类，外层代码一行不动。这一篇来兑现第一个承诺：把内存仓储换成 MyBatis-Plus，订单落进 MySQL。接口契约我一个字没改，坑倒是比预想的多，那个悬了两篇的 Jackson 3 坑也在这一篇掉进去了。&lt;/p&gt;</description></item><item><title>SpringBoot4系列01 - 实现RESTful接口</title><link>https://xiongneng.me/posts/java/springboot/sb4-restful/</link><pubDate>Thu, 17 Sep 2026 22:00:00 +0800</pubDate><author>yidao620@163.com (XiongNeng)</author><guid>https://xiongneng.me/posts/java/springboot/sb4-restful/</guid><category domain="https://xiongneng.me/categories/java/">Java</category><description>&lt;p&gt;前两天在群里看到有人贴了一段接口返回，长这样。&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;{&amp;#34;code&amp;#34;: 0, &amp;#34;msg&amp;#34;: &amp;#34;success&amp;#34;, &amp;#34;data&amp;#34;: {&amp;#34;id&amp;#34;: 1, &amp;#34;name&amp;#34;: &amp;#34;张三&amp;#34;}}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;出错了也是这个结构，只是 &lt;code&gt;code&lt;/code&gt; 变成 1，&lt;code&gt;msg&lt;/code&gt; 变成错误信息，HTTP 状态码永远是 200。贴出来的人说前端已经按这个格式对接了，改不动了。&lt;/p&gt;</description></item></channel></rss>