任意のストレージは、シリアル化が必要
任意のストレージは、シリアル化が必要。しかし、ルーチン、あなたが使用しているDBのストレージのクラス時、この事は、あなたが内部的に達成しているDBのヘルプ(直接にしてSQLデータ型に変換された内部シリアル化形式、ストレージを、と読むとき、それを解析します)。
Redisのはありませんあなたが助けるのシーケンスこの事を。あなたはRedisのキーと値、使用した場合のRedisのために価値を言えば、あるバイト配列は、必要とし、必要なデータ構造は変換バイト配列読むときなど、ストレージ、読み出しました。
- 場合は、文字列から、文字列はほとんど持っていたバイト配列を、そうで対処する必要はありません。
- もしboolean型の真/偽の;あなたはRedisのは、真と偽を表す方法で自分自身を定義する必要があります。たとえば、あなたが真のために1を使用することができ、0は偽を表します。また、この文字列がfalseを表し、この文字列は真、「偽」を表す「true」を使用することができます。
- 場合はデジタル、それは文字列表現を直接保存することができます(5 - >「5」)、その後(のparseInt / parseDouble / ...)が読み出されたデジタル文字列を元に戻します。
- 場合は、時間/日付、あなたは、このようなこの番号のEPOCのタイムスタンプ文字列表現として、自分自身を表現する文字列を定義するか、ISO8601形式であることができます。
- 場合は複雑なデータ構造、あなたはあなた自身を必要とするいくつかの直列化形式で保存することができ、JSON、いるProtobuf、アブロ、Javaの直列、Pythonのピクルス ......
春の背面側、SpringのredisTemplateは、デフォルトで使用されるJavaのシリアライズは、シリアル化を行います。使用している場合StringRedisTemplateを、あなたはしているすべてのデータセットがされますRedisの保つために少し長くToStringメソッド年。しかし、これのtoString 必ずしも抗分析バック......
特に覚えて速い、KryoRedisSerializerのシーケンスを!
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.io.ByteArrayOutputStream;
/**
* @param <T>
* @author 阿啄debugIT
*/
public class KryoRedisSerializer<T> implements RedisSerializer<T> {
Logger logger = LoggerFactory.getLogger(KryoRedisSerializer.class);
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
private static final ThreadLocal<Kryo> kryos = ThreadLocal.withInitial(Kryo::new);
private Class<T> clazz;
public KryoRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return EMPTY_BYTE_ARRAY;
}
Kryo kryo = kryos.get();
kryo.setReferences(false);
kryo.register(clazz);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
Output output = new Output(baos)) {
kryo.writeClassAndObject(output, t);
output.flush();
return baos.toByteArray();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return EMPTY_BYTE_ARRAY;
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
Kryo kryo = kryos.get();
kryo.setReferences(false);
kryo.register(clazz);
try (Input input = new Input(bytes)) {
return (T) kryo.readClassAndObject(input);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
}
要するに、それは単に、あなたが形成しなければならない規則の一連のことを確実にするために何かに預金をすることができ、エラーが戻ってこない解決。
優秀なリンクを説明します。
- https://blog.csdn.net/yuyeqianhen/article/details/90080532
- https://blog.csdn.net/moshowgame/article/details/83246363
内部クラスとしてアリFastJson2JsonRedisSerializer.java
SpringBoot + Redisの+ SpringCacheキャッシュとして内部クラスFastJson2JsonRedisSerializer.javaアリ、RedisConfigとして使用すると達成強化連載。
package AAAAAAAAAAA.common.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.time.Duration;
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private long maxWaitMillis;
@Bean
public JedisPool redisPoolFactory() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
if (StringUtils.isNotBlank(password)) {
return new JedisPool(jedisPoolConfig, host, port, timeout, password);
} else {
return new JedisPool(jedisPoolConfig, host, port, timeout);
}
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
jedisClientConfiguration.connectTimeout(Duration.ofMillis(timeout));
jedisClientConfiguration.usePooling();
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration.build());
}
@Bean(name = "redisTemplate")
@SuppressWarnings({"unchecked", "rawtypes"})
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
// 全局开启AutoType,不建议使用
// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// 建议使用这种方式,小范围指定白名单
ParserConfig.getGlobalInstance().addAccept("com.xiaolyuh.");
//使用 fastjson 序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// value 值的序列化采用 fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key 的序列化采用 StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
//缓存管理器
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory);
return builder.build();
}
@Bean
@ConditionalOnMissingBean(StringRedisTemplate.class)
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public KeyGenerator wiselyKeyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}
@Bean
public RedisTemplate<String, Serializable> limitRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Serializable> template = new RedisTemplate<>();
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
FastJsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes==null||bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
}
コード分析
- 使用StringRedisSerializerがやるの直列化キーの時間を、のStringRedisSerializer ジェネリック医薬品に指定された文字列は、キー属性のみが来るように文字列を渡すことができます別のオブジェクトの型変換エラーが@Cacheable注釈の使用で報告されます渡します。この連載では、一般的なオブジェクトに、書き換え。
- 使用FastJsonは、シリアライザの一部を書き換えシリアライズ値を行い、およびインタフェースRedisSerializerを実装します。
最新のを使用することをお勧めアリFastJsonは、いくつかの避ける頼る以前のバージョンで、リモートでコードがリスクの高いセキュリティで実行される脆弱性を
<!-- 1.2.41是最新的版本 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
リンク: