实测 AbstractRoutingDataSource 做读写分离:直接用时 readOnly 事务也路由到了主库,因为取连接时 readOnly 标记还没设置;外面包一层 LazyConnectionDataSourceProxy 后 readOnly 事务才走从库;readOnly 外层里调 REQUIRED 的写方法被驱动拦住,调 REQUIRES_NEW 的写方法则走主库。
实测 Spring Boot 4.0.8 加 Flyway 11:迁移按版本号数值顺序执行(V1、V1_1、V2、V10);改了已执行的 V 脚本会因校验和不一致启动失败,R 脚本改了则重跑;迟到的小版本号脚本默认校验失败;MySQL 上脚本中途失败会留下半截的表与 success=0 的历史行,再次启动报 Detected failed migration;非空库第一次接入需要 baseline,基线版本默认为 1,V1 会被跳过。
实测 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 Cache 加 Redis:key 是「缓存名::key」且默认永不过期;cache-null-values 默认 true,null 也被缓存挡住穿透;sync = true 在默认的 Redis 缓存写入器下并不加锁(30 个线程执行 30 次),换成 lockingRedisCacheWriter 后只执行 1 次且跨进程有效;TTL 统一会同时过期,用 TtlFunction 可以打散。
实测 Spring Security 7 的 FilterChainProxy:默认链有 16 个过滤器;两条链时每个请求只选第一条匹配的链(/api/** 链 11 个、兜底链 15 个);401 触发的 /error 派发会被兜底链拦下变成 302 到 /login;兜底链放在前面会在启动时失败;ignoring 的路径完全不经过过滤器,没有安全响应头,permitAll 的路径仍然经过 11 个过滤器。
实测 Spring Security 7 的认证流程:ProviderManager 里默认只有一个 DaoAuthenticationProvider;密码错与用户不存在都是 BadCredentialsException,耗时相近;禁用、锁定、凭据过期有各自的异常和事件;成功返回的是新对象,凭据被擦掉并多了 FACTOR_PASSWORD 权限;SecurityContext 默认只在请求线程里有,INHERITABLETHREADLOCAL 会让线程池里一直是第一次请求的用户。
实测 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 7 的登录态:表单登录后 SecurityContext 存在服务端 HttpSession 的 SPRING_SECURITY_CONTEXT,cookie 只有 JSESSIONID(HttpOnly);登录前后 session id 默认会变,关掉后不变;STATELESS 模式不创建会话;自己写登录接口只 setContext 而不 saveContext,下一个请求就没登录;退出后旧 cookie 失效。
实测 Spring Security 7 的 CSRF:默认令牌每次取到的值不同(96 字符的掩码)但都能通过校验;POST、DELETE 不带令牌 403,GET、HEAD、OPTIONS 放行;登录后旧令牌作废;Cookie 方案下把 36 字符的 cookie 值原样放进请求头会被默认处理器拒绝,换成明文处理器才通过;ignoringRequestMatchers 只放行指定路径。
实测 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 7 的方法级安全:@PreAuthorize 靠 CGLIB 代理实现,类内部自调用和 private 方法绕过检查,接口上的注解有效;@PostAuthorize 在方法执行之后才拒绝;@PreFilter 对不可变列表不报错也不过滤;@Secured 与 @RolesAllowed 在默认的 @EnableMethodSecurity 下完全不生效。
实测 Spring Security 7 的授权:hasRole("X") 等价于 hasAuthority("ROLE_X"),权限叫 ADMIN 的用户过不了 hasRole("ADMIN");hasRole("ROLE_ADMIN") 启动失败;规则按声明顺序第一个匹配的生效,写反会让 /a/admin/** 被 /a/** 的 USER 规则吞掉;anyRequest 之后不能再加 requestMatchers;RoleHierarchy 让 ADMIN 自动拥有 USER;自定义 AuthorizationManager 可以按请求信息决策。