序列化代理模式通过代理类替代原始对象参与序列化,防止绕过构造器、破坏不可变性及篡改transient字段;适用于含嵌套对象、集合、final字段、敏感数据或校验逻辑的复杂类。

序列化代理模式是提升复杂对象序列化安全性与健壮性的有效手段,核心在于用一个受控的代理类替代原始对象直接参与序列化流程,从而切断外部对构造逻辑、字段状态和约束条件的绕过路径。
为什么复杂变量对象需要代理模式
含嵌套对象、集合、final字段、transient敏感数据或业务校验逻辑的类,直接实现Serializable极易引发问题:
- 攻击者可伪造字节流跳过构造器,绕过不可变性(如直接设置
start晚于end的Period) -
transient字段仍可能被反射篡改或通过反序列化钩子注入
代理类的设计要点
代理类不是简单拷贝字段,而是精确建模“逻辑状态”:
- 必须为
private static class,避免持有外围类引用导致内存泄漏 - 字段类型与数量应与主类当前稳定状态严格一致(不暴露内部临时字段或缓存)
- 构造器仅做字段赋值,不做校验——校验留给主类构造器或
readResolve - 显式声明
serialVersionUID,隔离代理类自身的版本演进
关键方法的协同机制
writeReplace和readResolve构成安全闭环:
-
writeReplace():序列化前返回代理实例,确保磁盘/网络中只存在代理字节流,原始类实例永不落盘 -
readResolve():反序列化后由代理重建主类实例,调用真实构造器完成校验与保护性拷贝 - 配套
readObject抛出InvalidObjectException:彻底禁用原始类的反序列化入口,防止攻击者绕过代理
应对版本变更的实际处理
当主类结构升级(如增加phoneNumber),只需同步更新代理类字段与构造逻辑:
- 旧版本客户端反序列化新格式时,因代理类字段缺失而自然失败,可通过
OptionalFieldAttribute(.NET)或自定义readExternal(Java Externalizable)兼容;但代理模式本身建议“小步迭代+显式迁移” - 代理类自身可版本化(如
SerializationProxyV2),配合writeReplace逻辑分支,实现平滑过渡 - 所有字段初始化默认值(如
String phone = ""),避免反序列化后出现null引发NPE










