序列化
·
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
·序列化使其他代码可以查看或修改,那些不序列化便无法访问的对象实例数据。确切地说,代码执行序列化需要特殊的权限:即指定了 SerializationFormatter 标志的 SecurityPermission。在默认策略下,通过 Internet 下载的代码或 Internet 代码不会授予该权限;只有本地计算机上的代码才被授予该权限。
·通常,对象实例的所有字段都会被序列化,这意味着数据会被表示为实例的序列化数据。这样,能够解释该格式的代码有可能能够确定这些数据的值,而不依赖于该成员的可访问性。类似地,反序列化从序列化的表示形式中提取数据,并直接设置对象状态,这也与可访问性规则无关。
·对于任何可能包含重要的安全性数据的对象,如果可能,应该使该对象不可序列化。如果它必须为可序列化的,请尝试生成特定字段来保存不可序列化的重要数据。如果无法实现这一点,则应注意该数据会被公开给任何拥有序列化权限的代码,并确保不让任何恶意代码获得该权限。
内容摘自百科:序列化
简而言之:
- 序列化:将
对象
转换成字节流
的过程。 - 反序列化:将
字节流
转换成对象
的过程。
那么,什么情况才需要用到它呢?
- 因为ta的定义,我们可以想象的到
a、数据持久化
b、对象传输(进程间/网络中)
序列化方式
- Serializable Java内置序列化API
- Protobuf Google提供高效序列化API
- Protostuff 开源社区基于
Protobuf
封装API
以上仅做例子,那么做出选择的动机是什么呢?
开发过程中,由上面的用途中,我们可以联想到:
- 时间上:尽可能快
- 空间上:尽可能小
- 操作上:尽可能便捷
由此可进行简单对比:
Serializable 相对速度慢、占空间、操作便捷(可序列化所有类)
Protobuf 相对速度快、空间占用小、操作繁琐(中间过程多)
Protostuff 相比速度快、空间小、操作便捷(隐藏Protobuf中间细节)
实际对比可参照 # [java]序列化框架性能对比(kryo、hessian、java、protostuff)
- 可以得出
Protostuff
占用小,速度快 -> 适合做数据存储或 RPC 数据交换格式 - 但又由于
Protostuff
序列化后,可读性差
- 生产环境优先选择
Protostuff
- 开发环境可选择
Serializable
(可读性对友方友好,易调戏/试)
实践
Maven
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
io.protostuff
protostuff-core
io.protostuff
protostuff-runtime
Protostuff序列化工具类
public class ProtostuffSerializer implements RedisSerializer
此时可以拿工具进行测验啦
替换Redis序列化默认配置
@Configuration
public class RedisCacheConfig {
@Bean
public RedisTemplate redisTemplate(LettuceConnectionFactory factory) {
RedisTemplate template = new RedisTemplate<>();
factory.setDatabase(cacheDbIdx);
template.setConnectionFactory(factory);
// 使用ProtostuffSerializer 替换默认序列化
RedisSerializer serializer = new ProtostuffSerializer();
// 设置value的序列化规则和 key的序列化规则
template.setKeySerializer(serializer);
template.setValueSerializer(serializer);
template.setDefaultSerializer(serializer);
template.setHashKeySerializer(serializer);
template.setHashValueSerializer(serializer);
template.setStringSerializer(serializer);
template.afterPropertiesSet();
// template.setEnableTransactionSupport(true);
return template;
}
}
二级缓存类
@Slf4j
public class MplusRedisCache implements Cache {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private String id;
public MplusRedisCache(String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
log.debug("[创建了mybatis的redis缓存:{}]" + id);
}
private RedisTemplate
测试结果~
至此Protostuff简易使用完成啦~