前言
不知不觉写代码也有近10年的时间了,回忆了一下,一直都在向行业内的前辈们借鉴经验,自己却没有什么贡献,想想有点惭愧。最近准备读一下Spring的源码以加强和补充知识体系,趁着这个机会,想把以往的经历和体验梳理一下分享出来,希望可以帮助到一些需要帮助的人,同时对于自己也是一个总结和积累。话不多说上正题。
什么是序列化
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
以上是序列化的定义和解释,用更加通俗的语言来描述:序列化就是内存对象转磁盘数据与磁盘数据转内存对象的处理过程。其中,内存对象转磁盘数据叫做序列化;磁盘数据转内存对象叫做反序列化。
序列化的作用
序列化最直观的作用就是可以用于运行时对象的持久化,这方面使用比较频繁的是堆信息的序列化,用于程序运行时问题的排查,也可以用于对象传输,比如,把同一个版本的类实例序列化后传输到另外一台机器上进行反序列化,类似于缓存集群的主从复制,另外见过一些通过序列化和反序列化进行对象深拷贝的例子(这是一种偷懒的方式,性能方面存在问题,如果频繁使用需要慎重)
序列化的处理前提
Java使用序列化的前提是对象的类必须实现Serializable接口,实现该接口的类需要定义属性serialVersionUID,该字段是对象实现序列化的参考依据,如下例:
package com.***.bean;
import java.io.Serializable;
/**
* 基础实例基类
*
* @version 1.0.0
* @since JDK 8.0
*/
public class BaseBean implements Serializable {
/**
* 序列化版本编号
*/
private static final long serialVersionUID = 90489455520886134L;
}
序列化跳过
Java内置了序列化忽略的关键字(transient),用于灵活指定序列化字段。
/**
* 标题(指定忽略序列化)
*/
private transient String title;
Spring的序列化封装
Spring序列化的封装包位于spring-core项目下的org.springframework.core.serializer包内
Serializer接口
/**
* Write an object of type T to the given OutputStream.
* <p>Note: Implementations should not close the given OutputStream
* (or any decorators of that OutputStream) but rather leave this up
* to the caller.
* @param object the object to serialize
* @param outputStream the output stream
* @throws IOException in case of errors writing to the stream
*/
void serialize(T object, OutputStream outputStream) throws IOException;
该接口定义了对象序列化的处理,仅有一个对象序列化的声明方法。
DefaultSerializer类
该类是Spring提供的默认序列化实现类,提供了对象序列化的具体处理,可以使用该类的对象进行对象的序列化操作
/**
* 序列化测试类
*/
public static void serializerTest() {
DefaultSerializer defaultSerializer