Java 安全实践不只包括登录鉴权。缓存、分布式锁、序列化、第三方对象处理和反序列化边界,都会影响系统稳定性和安全性。很多问题并不是“被攻击”才出现,而是数据格式、对象生命周期和默认配置不清楚导致的。
缓存工具选型要看一致性边界
Spring Cache、Redis Cache、多级缓存、Caffeine、l2cache 这类工具都能提高读取性能,但它们解决的问题不完全一样。
选型前先问:
- 数据是否允许短暂不一致。
- 是否需要本地缓存加远程缓存。
- key 命名和过期策略谁负责。
- 缓存更新失败时业务怎么降级。
- 是否需要统一注解,还是明确写缓存逻辑。
缓存不是越多越好。多级缓存会带来更复杂的失效和排障成本,适合热点稳定、读多写少、可接受短暂不一致的场景。
分布式锁要用成熟实现
分布式锁常见于防重复提交、定时任务互斥、库存扣减和资源串行化处理。简单 setnx 只能说明方向,不足以覆盖完整生产边界。
可靠的锁至少要考虑:
- 加锁和过期要原子。
- value 要能标识持锁者。
- 释放锁时只能释放自己的锁。
- 锁过期前业务是否一定能执行完。
- 失败重试是否会造成重复执行。
复杂场景优先使用成熟库,例如 Redisson 或 Lock4j,而不是在业务里散落手写锁。
序列化问题经常来自对象边界
Java 项目里常见问题是:对象有 getter 没有 setter,或者第三方类不符合 JavaBean 约定,导致 JSON 序列化或反序列化失败。
处理思路可以分层:
- 能改源码时,给不该暴露的字段加
@JsonIgnore。 - 不能改第三方类时,用 Jackson MixIn 或 Filter 控制字段。
- 只需要本地缓存时,谨慎评估 Java 原生序列化。
- 对外接口尽量使用明确 DTO,不直接暴露复杂第三方对象。
最重要的是不要为了“能序列化”把所有字段都打开。对象里可能包含权限、会话、内部状态或敏感信息。
反序列化默认配置要保守
Jackson、Fastjson 等工具都有大量配置项。为了兼容旧对象,有人会打开更宽松的可见性、默认类型或忽略未知字段。
这些配置要明确限定使用范围。尤其是类型信息、默认反序列化、多态对象,如果对外开放,可能引入安全风险。
更稳的做法是:外部请求先落到明确的请求 DTO,字段经过校验后,再转换成内部对象。不要让外部 JSON 直接驱动任意内部类型创建。
GPU 和特殊能力要先验证边界
Java 调用 GPU、原生库、JNI 或外部工具,都属于跨边界能力。可行不代表适合当前项目。
引入前至少要确认:
- 部署机器是否有对应硬件和驱动。
- 依赖是否跨平台。
- 错误和超时如何处理。
- 是否有替代的服务化方案。
- 监控和日志能否覆盖。
特殊能力越强,运维边界越要清楚。
实用结论
Java 安全实践是“边界管理”:缓存边界、锁边界、序列化边界、第三方类边界和运行环境边界。
把默认配置收紧,把对外 DTO 明确,把敏感字段隔离,把分布式锁交给成熟实现,比事后靠日志猜问题更可靠。




