首先引入 msgpack 所需要的包
<dependency><groupId>org.msgpack</groupId><artifactId>msgpack-core</artifactId><version>0.8.13</version></dependency><dependency><groupId>org.msgpack</groupId><artifactId>jackson-dataformat-msgpack</artifactId><version>0.8.13</version></dependency>
- 版本一定要对齐,之前 jackson-dataformat-msgpack 版本太低导致无法使用。
RedisConfig.java(Spring Boot Redis 配置类)
importcom.fasterxml.jackson.databind.ObjectMapper; importorg.msgpack.jackson.dataformat.MessagePackFactory; importorg.springframework.cache.annotation.CachingConfigurerSupport; importorg.springframework.cache.annotation.EnableCaching; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.data.redis.cache.RedisCacheConfiguration; importorg.springframework.data.redis.connection.RedisConnectionFactory; importorg.springframework.data.redis.core.RedisTemplate; importorg.springframework.data.redis.core.StringRedisTemplate; importorg.springframework.data.redis.serializer.*; publicclassRedisConfigextendsCachingConfigurerSupport { /*** 设置spring redis data 序列化模板* @param factory* @return*/publicRedisTemplateredisTemplate(RedisConnectionFactoryfactory) { StringRedisTemplatetemplate=newStringRedisTemplate(factory); ObjectMappermapper=newObjectMapper(newMessagePackFactory()); Jackson2JsonRedisSerializerJackson2Serializer=newJackson2JsonRedisSerializer(Object.class); Jackson2Serializer.setObjectMapper(mapper); RedisSerializerredisSerializer=Jackson2Serializer; template.setValueSerializer(redisSerializer); template.setKeySerializer(newStringRedisSerializer()); returntemplate; } /*** 整合spring cache* 设置@cacheable 序列化方式* @return*/publicRedisCacheConfigurationredisCacheConfiguration() { RedisCacheConfigurationconfiguration=RedisCacheConfiguration.defaultCacheConfig(); configuration=configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(newGenericMsgpackRedisSerializer())); returnconfiguration; } }
GenericMsgpackRedisSerializer.java(Spring Cache msgpack 序列化类)
importcom.fasterxml.jackson.annotation.JsonTypeInfo.As; importcom.fasterxml.jackson.core.JsonGenerator; importcom.fasterxml.jackson.core.JsonProcessingException; importcom.fasterxml.jackson.databind.ObjectMapper; importcom.fasterxml.jackson.databind.SerializerProvider; importcom.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; importcom.fasterxml.jackson.databind.module.SimpleModule; importcom.fasterxml.jackson.databind.ser.std.StdSerializer; importjava.io.IOException; importorg.msgpack.core.annotations.Nullable; importorg.msgpack.jackson.dataformat.MessagePackFactory; importorg.springframework.cache.support.NullValue; importorg.springframework.data.redis.serializer.RedisSerializer; importorg.springframework.data.redis.serializer.SerializationException; importorg.springframework.util.Assert; importorg.springframework.util.StringUtils; publicclassGenericMsgpackRedisSerializerimplementsRedisSerializer<Object> { staticfinalbyte[] EMPTY_ARRAY=newbyte[0]; privatefinalObjectMappermapper; publicGenericMsgpackRedisSerializer() { this.mapper=newObjectMapper(newMessagePackFactory()); this.mapper.registerModule((newSimpleModule()).addSerializer(newGenericMsgpackRedisSerializer.NullValueSerializer(null))); this.mapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY); } publicbyte[] serialize(Objectsource) throwsSerializationException { if (source==null) { returnEMPTY_ARRAY; } else { try { returnthis.mapper.writeValueAsBytes(source); } catch (JsonProcessingExceptionvar3) { thrownewSerializationException("Could not write JSON: "+var3.getMessage(), var3); } } } publicObjectdeserialize(byte[] source) throwsSerializationException { returnthis.deserialize(source, Object.class); } public<T>Tdeserialize(byte[] source, Class<T>type) throwsSerializationException { Assert.notNull(type, "Deserialization type must not be null! Pleaes provide Object.class to make use of Jackson2 default typing."); if (source==null||source.length==0) { returnnull; } else { try { returnthis.mapper.readValue(source, type); } catch (Exceptionvar4) { thrownewSerializationException("Could not read JSON: "+var4.getMessage(), var4); } } } privateclassNullValueSerializerextendsStdSerializer<NullValue> { privatestaticfinallongserialVersionUID=2199052150128658111L; privatefinalStringclassIdentifier; NullValueSerializer(StringclassIdentifier) { super(NullValue.class); this.classIdentifier=StringUtils.hasText(classIdentifier) ?classIdentifier : "@class"; } publicvoidserialize(NullValuevalue, JsonGeneratorjgen, SerializerProviderprovider) throwsIOException { jgen.writeStartObject(); jgen.writeStringField(this.classIdentifier, NullValue.class.getName()); jgen.writeEndObject(); } } }
RedisCacheRedisUtils.java(序列化工具类)
importjava.util.Set; importcom.fasterxml.jackson.databind.ObjectMapper; importorg.msgpack.jackson.dataformat.MessagePackFactory; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.data.redis.connection.RedisConnectionFactory; importorg.springframework.data.redis.core.*; importorg.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; importorg.springframework.data.redis.serializer.RedisSerializer; importorg.springframework.stereotype.Component; importjavax.annotation.Resource; /*** @description: redis缓存工具类* @version:1.0*/publicclassRedisCacheUtils { privatestaticLoggerlogger=LoggerFactory.getLogger(RedisCacheUtils.class); privatefinalstaticBooleanREDIS_ENABLE=true; privateRedisTemplateredisTemplate; RedisConnectionFactoryredisConnectionFactory; publicRedisTemplategetRedisTemplate() { returnredisTemplate; } publicvoidsetRedisTemplate(RedisTemplateredisTemplate) { this.redisTemplate=redisTemplate; } publicRedisCacheUtils(RedisTemplateredisTemplate) { this.redisTemplate=redisTemplate; } /*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @return缓存的对象 */publicbooleansetCacheObject(Stringkey, Objectvalue) { if (!REDIS_ENABLE) { returnfalse; } logger.debug("存入缓存 key:"+key); try { ValueOperations<String, Object>operation=redisTemplate.opsForValue(); operation.set(key, value); returntrue; } catch (Exceptionex) { logger.error(ex.getMessage()); returnfalse; } } /*** 根据pattern匹配清除缓存* @param pattern*/publicvoidclear(Stringpattern) { if (!REDIS_ENABLE) { return; } logger.debug("清除缓存 pattern:"+pattern); try { ValueOperations<String, Object>valueOper=redisTemplate.opsForValue(); RedisOperations<String, Object>redisOperations=valueOper.getOperations(); redisOperations.keys(pattern); Set<String>keys=redisOperations.keys(pattern); for (Stringkey : keys) { redisOperations.delete(key); } } catch (Exceptionex) { logger.error(ex.getMessage()); return; } } /*** 根据key清除缓存* @param key*/publicvoiddelete(Stringkey) { if (!REDIS_ENABLE) { return; } logger.debug("删除缓存 key:"+key); try { ValueOperations<String, Object>valueOper=redisTemplate.opsForValue(); RedisOperations<String, Object>redisOperations=valueOper.getOperations(); redisOperations.delete(key); } catch (Exceptionex) { logger.error(ex.getMessage()); return; } } /*** 获得缓存的基本对象。* @param key 缓存键值* @return 缓存键值对应的数据* */publicObjectgetCacheObject(Stringkey) { if (!REDIS_ENABLE) { returnnull; } logger.debug("获取缓存 key:"+key); try { ValueOperations<String, Object>operation=redisTemplate.opsForValue(); returnoperation.get(key); } catch (Exceptionex) { logger.error(ex.getMessage()); returnnull; } } /*** 获得缓存的基本对象。* @param key 缓存键值* @return 缓存键值对应的数据* */public<T>TgetCacheObject(Stringkey, Class<T>clazz) { if (!REDIS_ENABLE) { returnnull; } logger.debug("获取缓存 key:"+key); RedisTemplatetemplate=newStringRedisTemplate(redisConnectionFactory); Jackson2JsonRedisSerializerJackson2Serializer=newJackson2JsonRedisSerializer(clazz); Jackson2Serializer.setObjectMapper(newObjectMapper(newMessagePackFactory())); RedisSerializerredisSerializer=Jackson2Serializer; template.setValueSerializer(redisSerializer); try { ValueOperations<String, T>operation=template.opsForValue(); return (T) operation.get(key); } catch (Exceptionex) { logger.error(ex.getMessage()); returnnull; } } }
启动 Spring Boot 开始测试
publicclassTestController { RedisCacheUtilsredisCacheUtils; "/getCache") (publicObjectgetCache() { List<String>result=redisCacheUtils.getCacheObject("list_cache", newArrayList<HashMap<String, String>>().getClass()); returnresult; } "/setCache") (publicObjectsetCache() { List<Map>list=newArrayList<>(); for (inti=0; i<100; i++) { Mapmap=newHashMap<String, String>(); map.put("id", i); map.put("name", "index="+i); list.add(map); } returnredisCacheUtils.setCacheObject("list_cache", list); } }
- 缓存结果(msgpack:大小1893字节)
- 缓存结果(fastjson:大小2781字节)
- 速度比较(10000条数据测试,非专业测试结果,仅供参考)
排名结果:msgpack > fastJson > jackson