分布式:序列化和反序列化详解

一、定义及常用实现方式


1、序列化,反序列化的定义

序列化:序列化就是把一个对象变成二进制或者是一个有序的字节数组进行序列化来。
反序列化:把一个有序的字节流的对象重新加载为一个对象。
在分布式的中对程序的优化是非常重要的,只要在网络中进行 传输的话物理层之间的交互都需要序列化。

2、java中自带的序列化

让其序列化的类实现Serializable接口:缺点:1:它是不能实现跨语言的。2:序列化之后的文件大小很大。在网络中传输的带宽是很大的。在分布式中用的非常少。3:序列的时候没有实现这个接口就报错。

3、WebService的序列化

流量大的话:可以用WebService替代(SOAP协议),xml文件做传输介质的,用xml方式来做序列化的。在网络中进行传输。很长一段时间都是用webService作为序列化主流的。可以自己去扩展,可读性很强。很多的接口还是提供了XML文件的方式。因为 很多的老项目还在使用WebService去实现远程的调用。比如银行还在用,支付接口。主要作用,把远程的过程封装起来给你调用的接口,返回xml格式。

4、主流的框架来序列化

针对java语言特有的:FST,Kryo(高性能的序列化框架) 跨语言的序列化框架:jackson,fastson,protobuffer,protosutff,protobuf,gson。messagepack,avro(针对大数据的),thrift(rpc框架,也是序列化架),hessian2(dubbo原有的序列化方式) 现在dubbo开始支持的序列化框架也有FST和kryo了。

二、代码实现


1、序列化代码实现
分布式:序列化和反序列化详解_第1张图片
这个UUID代表这个类序列化的一种标识。也做为虚拟机的一种入口的验证,有点类似加密和解密。
分布式:序列化和反序列化详解_第2张图片
然后同步一下idea:就出现这个的文件。
分布式:序列化和反序列化详解_第3张图片
然后把这个文件拖到sublime里面去会显示:这就是二进制字节码。不是乱码
实际上它是二进制转成16进制的一个显示。这就是已经序列化到这个文件中去了。
分布式:序列化和反序列化详解_第4张图片
2、反序列化代码实现
分布式:序列化和反序列化详解_第5张图片
在这里插入图片描述
文件大小:
分布式:序列化和反序列化详解_第6张图片
分布式:序列化和反序列化详解_第7张图片

结论:每次增加得大小为5个字节,多次序列化,只是增加的是引用。不管序列化多少次,反序列化一次都能给它拿出。因为它会进行一个指针的拆分。在java虚拟机中做了一个这样的优化。这样的优化在后面的序列化框架中都有所呈现

3、问题扩展

在序列化中是否存在父子类序列化问题?比如说在父类中没有序列化,在子类中有序列化了。那么父类中的数据是否被序列化了呢?代码如下测试下

public class Human {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Human{" +
"name='" + name + '\'' +
'}';
}
}
import java.io.Serializable;

public class Person extends Human implements Serializable {
private String gender;
private int age;

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "Person{name=" +getName()+","+
"gender='" + gender + '\'' +
", age=" + age +
'}';
}
}
import java.io.*;

public class PersonDemoTest {
public static void main(String[] args) throws Exception{

Person person=new Person();
person.setAge(12);
person.setGender("男");
person.setName("魏召阳");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("person-nav"));
oos.writeObject(person);
oos.flush();
oos.close();
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("person-nav"));
Person person1 =(Person)ois.readObject();
System.out.println(person1);

}
}

测试结果:
分布式:序列化和反序列化详解_第8张图片
分布式:序列化和反序列化详解_第9张图片

结论:说明父类中没有进行序列化,子类中序列化,并不影响父类中的数据,但是它在这里不会报错的。 如果父类去实现Serrialize接口的话:这时就可以拿到了。在dubbo中如果稍微不注意就会出现问题,因为dubbo中也有相关的协议,这些协议是很严格的。如果不按照协议的话,数据是传送不过去的。

欢迎各位小伙伴来评价,想要工程代码的加群:797853299

你可能感兴趣的:(分布式,java)