知其然,知其所以然
Spring 全家桶 2026-10-20

读写分离:AbstractRoutingDataSource 与事务内路由

实测 AbstractRoutingDataSource 做读写分离:直接用时 readOnly 事务也路由到了主库,因为取连接时 readOnly 标记还没设置;外面包一层 LazyConnectionDataSourceProxy 后 readOnly 事务才走从库;readOnly 外层里调 REQUIRED 的写方法被驱动拦住,调 REQUIRES_NEW 的写方法则走主库。

Spring JDBC 读写分离 AbstractRoutingDataSource 事务 LazyConnectionDataSourceProxy 真实验证 动画演示
Spring 全家桶 2026-10-20

Flyway:迁移顺序、校验和与失败后的状态

实测 Spring Boot 4.0.8 加 Flyway 11:迁移按版本号数值顺序执行(V1、V1_1、V2、V10);改了已执行的 V 脚本会因校验和不一致启动失败,R 脚本改了则重跑;迟到的小版本号脚本默认校验失败;MySQL 上脚本中途失败会留下半截的表与 success=0 的历史行,再次启动报 Detected failed migration;非空库第一次接入需要 baseline,基线版本默认为 1,V1 会被跳过。

Spring Boot Flyway 数据库迁移 校验和 真实验证 动画演示
Spring 全家桶 2026-10-20

Spring Data Redis:Lettuce、序列化器与 pipeline

实测 Spring Data Redis 4 与 Lettuce:默认 RedisTemplate 用 JDK 序列化,key 前面带 \xac\xed 头、value 161 字节而 JSON 只要 42 字节;64 个线程共用 1 个 Lettuce 连接约 95000 次/秒,开连接池要关掉共享连接才会起作用且更慢;10000 个 SET 循环 461 ms、pipeline 67 ms、MSET 10 ms;Redis 宕机时每个命令等满超时才失败,恢复后重连一次 1413 ms。

Spring Data Redis Lettuce 序列化 pipeline 真实验证 动画演示
Spring 全家桶 2026-10-20

Spring Cache + Redis:穿透、击穿、雪崩的配置位置

实测 Spring Cache 加 Redis:key 是「缓存名::key」且默认永不过期;cache-null-values 默认 true,null 也被缓存挡住穿透;sync = true 在默认的 Redis 缓存写入器下并不加锁(30 个线程执行 30 次),换成 lockingRedisCacheWriter 后只执行 1 次且跨进程有效;TTL 统一会同时过期,用 TtlFunction 可以打散。

Spring Cache Redis 缓存穿透 缓存击穿 缓存雪崩 真实验证 动画演示
Spring 全家桶 2026-10-20

FilterChainProxy:安全过滤器链的顺序,多条链怎么匹配

实测 Spring Security 7 的 FilterChainProxy:默认链有 16 个过滤器;两条链时每个请求只选第一条匹配的链(/api/** 链 11 个、兜底链 15 个);401 触发的 /error 派发会被兜底链拦下变成 302 到 /login;兜底链放在前面会在启动时失败;ignoring 的路径完全不经过过滤器,没有安全响应头,permitAll 的路径仍然经过 11 个过滤器。

Spring Security FilterChainProxy 过滤器链 securityMatcher 真实验证 动画演示
Spring 全家桶 2026-10-20

认证流程:AuthenticationManager、Provider 与 SecurityContext

实测 Spring Security 7 的认证流程:ProviderManager 里默认只有一个 DaoAuthenticationProvider;密码错与用户不存在都是 BadCredentialsException,耗时相近;禁用、锁定、凭据过期有各自的异常和事件;成功返回的是新对象,凭据被擦掉并多了 FACTOR_PASSWORD 权限;SecurityContext 默认只在请求线程里有,INHERITABLETHREADLOCAL 会让线程池里一直是第一次请求的用户。

Spring Security 认证 AuthenticationManager SecurityContext 真实验证 动画演示
Spring 全家桶 2026-10-20

PasswordEncoder:BCrypt 的 cost 与耗时,DelegatingPasswordEncoder

实测 Spring Security 7 的 PasswordEncoder:BCrypt strength 每加 2 耗时约 ×4(10 是 70.1 ms,12 是 274.6 ms,14 是 1105.2 ms);DelegatingPasswordEncoder 用 {id} 前缀选算法,没有前缀会抛异常,upgradeEncoding 可以识别旧哈希;encode 拒绝超过 72 字节的密码,但 matches 会忽略 72 字节之后的内容;Pbkdf2、SCrypt、Argon2 的默认参数耗时。

Spring Security PasswordEncoder BCrypt DelegatingPasswordEncoder 真实验证 动画演示
Spring 全家桶 2026-10-20

Session 与 SecurityContextRepository:登录态存在哪里

实测 Spring Security 7 的登录态:表单登录后 SecurityContext 存在服务端 HttpSession 的 SPRING_SECURITY_CONTEXT,cookie 只有 JSESSIONID(HttpOnly);登录前后 session id 默认会变,关掉后不变;STATELESS 模式不创建会话;自己写登录接口只 setContext 而不 saveContext,下一个请求就没登录;退出后旧 cookie 失效。

Spring Security Session SecurityContextRepository 登录态 真实验证 动画演示
Spring 全家桶 2026-10-20

CSRF:令牌怎么生成与校验

实测 Spring Security 7 的 CSRF:默认令牌每次取到的值不同(96 字符的掩码)但都能通过校验;POST、DELETE 不带令牌 403,GET、HEAD、OPTIONS 放行;登录后旧令牌作废;Cookie 方案下把 36 字符的 cookie 值原样放进请求头会被默认处理器拒绝,换成明文处理器才通过;ignoringRequestMatchers 只放行指定路径。

Spring Security CSRF 令牌 CookieCsrfTokenRepository 真实验证 动画演示
Spring 全家桶 2026-10-20

CORS 与 Security:预检为什么被 401 拦下

实测 Spring Security 7 加 Spring MVC 的 CORS:MVC 里配了 CORS 而 Security 没有 .cors() 时,预检(不带凭据的 OPTIONS)被认证拦成 401,没有任何 CORS 头;加上 http.cors(withDefaults) 后预检 200 并返回 allow-origin、allow-methods、allow-headers、max-age 1800,不允许的 Origin、方法、请求头都是 403;需要凭据时用 allowedOriginPatterns。

Spring Security CORS 预检 跨域 真实验证 动画演示
Spring 全家桶 2026-10-20

方法级安全:@PreAuthorize 与代理

实测 Spring Security 7 的方法级安全:@PreAuthorize 靠 CGLIB 代理实现,类内部自调用和 private 方法绕过检查,接口上的注解有效;@PostAuthorize 在方法执行之后才拒绝;@PreFilter 对不可变列表不报错也不过滤;@Secured 与 @RolesAllowed 在默认的 @EnableMethodSecurity 下完全不生效。

Spring Security 方法级安全 PreAuthorize AOP代理 真实验证 动画演示
Spring 全家桶 2026-10-20

授权决策:AuthorizationManager 与 ROLE_ 前缀

实测 Spring Security 7 的授权:hasRole("X") 等价于 hasAuthority("ROLE_X"),权限叫 ADMIN 的用户过不了 hasRole("ADMIN");hasRole("ROLE_ADMIN") 启动失败;规则按声明顺序第一个匹配的生效,写反会让 /a/admin/** 被 /a/** 的 USER 规则吞掉;anyRequest 之后不能再加 requestMatchers;RoleHierarchy 让 ADMIN 自动拥有 USER;自定义 AuthorizationManager 可以按请求信息决策。

Spring Security 授权 AuthorizationManager ROLE_前缀 RoleHierarchy 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号