程序员子龙(Java面试 + Java学习) 程序员子龙(Java面试 + Java学习)
首页
学习指南
工具
开源项目
技术书籍

程序员子龙

Java 开发从业者
首页
学习指南
工具
开源项目
技术书籍
  • 基础

  • JVM

  • Spring

  • 并发编程

  • Mybatis

  • 网络编程

    • Netty 入门
    • Netty中的Option和ChildOption参数解析
    • Netty ByteBuf介绍
    • Netty 心跳机制
    • Kryo 的序列化和序列化
      • Netty粘包拆包
      • Netty 编解码器
      • 网络编程IO模式
      • Netty TCP长连接集群方案
      • 序列化和反序列化
      • 使用 UDP 的 Socket API 实现服务端
      • Netty向客户端发送及接收16进制数据
      • Spring Boot与Netty的完美结合:打造高性能网络通信
    • 数据库

    • 缓存

    • 设计模式

    • 分布式

    • 高并发

    • SpringBoot

    • SpringCloudAlibaba

    • Nginx

    • 面试

    • 生产问题

    • 系统设计

    • 消息中间件

    • Java
    • 网络编程
    程序员子龙
    2024-01-29
    目录

    Kryo 的序列化和序列化

    # Kryo 的序列化

    作为一个灵活的序列化框架,Kryo 并不关心读写的数据,作为开发者,你可以随意使用 Kryo 提供的那些开箱即用的序列化器。

    引入依赖

    <dependency>
        <groupId>de.javakaffee</groupId>
        <artifactId>kryo-serializers</artifactId>
        <version>0.42</version>
    </dependency>
    
    1
    2
    3
    4
    5

    使用工厂的方式实例化Kryo

    import com.esotericsoftware.kryo.Kryo;
    import com.esotericsoftware.kryo.serializers.DefaultSerializers;
    import de.javakaffee.kryoserializers.*;
    
    import java.lang.reflect.InvocationHandler;
    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.net.URI;
    import java.text.SimpleDateFormat;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.regex.Pattern;
    
    /**
     * Kryo的工厂,实例化Kryo
     */
    public class KryoFactory {
    
        public static Kryo createKryo() {
    
            Kryo kryo = new Kryo();
            kryo.setRegistrationRequired(false);
            kryo.register(Arrays.asList("").getClass(), new ArraysAsListSerializer());
            kryo.register(GregorianCalendar.class, new GregorianCalendarSerializer());
            kryo.register(InvocationHandler.class, new JdkProxySerializer());
            kryo.register(BigDecimal.class, new DefaultSerializers.BigDecimalSerializer());
            kryo.register(BigInteger.class, new DefaultSerializers.BigIntegerSerializer());
            kryo.register(Pattern.class, new RegexSerializer());
            kryo.register(BitSet.class, new BitSetSerializer());
            kryo.register(URI.class, new URISerializer());
            kryo.register(UUID.class, new UUIDSerializer());
            UnmodifiableCollectionsSerializer.registerSerializers(kryo);
            SynchronizedCollectionsSerializer.registerSerializers(kryo);
    
            kryo.register(HashMap.class);
            kryo.register(ArrayList.class);
            kryo.register(LinkedList.class);
            kryo.register(HashSet.class);
            kryo.register(TreeSet.class);
            kryo.register(Hashtable.class);
            kryo.register(Date.class);
            kryo.register(Calendar.class);
            kryo.register(ConcurrentHashMap.class);
            kryo.register(SimpleDateFormat.class);
            kryo.register(GregorianCalendar.class);
            kryo.register(Vector.class);
            kryo.register(BitSet.class);
            kryo.register(StringBuffer.class);
            kryo.register(StringBuilder.class);
            kryo.register(Object.class);
            kryo.register(Object[].class);
            kryo.register(String[].class);
            kryo.register(byte[].class);
            kryo.register(char[].class);
            kryo.register(int[].class);
            kryo.register(float[].class);
            kryo.register(double[].class);
    
            return kryo;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61

    封装序列化和反序列化工具

    import com.esotericsoftware.kryo.Kryo;
    import com.esotericsoftware.kryo.io.Input;
    import com.esotericsoftware.kryo.io.Output;
    
    import java.io.ByteArrayOutputStream;
    
    public class KryoSerializer {
        /**
         * 解决线程安全问题
         */
        private static final ThreadLocal<Kryo> kryoPool = ThreadLocal.withInitial(() -> {
            Kryo temp = KryoFactory.createKryo();
            temp.setReferences(false);
            return temp;
        });
    
        public static byte[] serialize(Object object) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream(4096);
            Output output = new Output(bos, 1024);
            kryoPool.get().writeClassAndObject(output, object);
            output.flush();
            return bos.toByteArray();
        }
    
        public static Object deserialize(byte[] bytes) {
            Input input = new Input(bytes);
            return kryoPool.get().readClassAndObject(input);
        }
    
        public static void setClassLoader(ClassLoader classLoader) {
            kryoPool.get().setClassLoader(classLoader);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    定义实体

    public class Param {
    
        public String name;
    
        public Integer age;
    
        public Map<String, Object> conf = new HashMap<>(4);
    
        public Param() {
        }
    
        public Param(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Param{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    测试的序列化和反序列化方法

    public class Test {
    
        private static void deserialize(String s) {
            System.out.println(Kryo.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    
            //s = "AQBjb20uamltby5QYXJh7QEBamF2YS51dGlsLkhhc2hNYfABA2517QLIAWppbe8=";
    
            final Object obj = KryoSerializer.deserialize(Base64.getDecoder().decode(s));
            System.out.println(obj);
        }
    
        private static String  serialize() {
            System.out.println(Kryo.class.getProtectionDomain().getCodeSource().getLocation().getPath());
            final Param p = new Param("zhangsan",20);
            p.conf.put("num", 100);
            final byte[] bytes = KryoSerializer.serialize(p);
            return Base64.getEncoder().encodeToString(bytes);
        }
    
        public static void main(String[] args) {
    
            deserialize( serialize());
    
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    /D:/.m2/repository/com/esotericsoftware/kryo/4.0.0/kryo-4.0.0.jar /D:/.m2/repository/com/esotericsoftware/kryo/4.0.0/kryo-4.0.0.jar Param{name='zhangsan', age=20}

    # 总结

    对于Kryo的兼容性问题,建议序列化和反序列化保持同一个版本,跨版本的兼容很难保证,特别是在有 Map的情况下。

    上次更新: 2024/01/30, 15:08:57
    Netty 心跳机制
    Netty粘包拆包

    ← Netty 心跳机制 Netty粘包拆包→

    最近更新
    01
    一个注解,优雅的实现接口幂等性
    11-17
    02
    MySQL事务(超详细!!!)
    10-14
    03
    阿里二面:Kafka中如何保证消息的顺序性?这周被问到两次了
    10-09
    更多文章>
    Theme by Vdoing | Copyright © 2024-2024

        辽ICP备2023001503号-2

    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式