最近在入門SpringBoot,而後在感慨 SpringBoot較於Spring真的方便多時,順便記錄下本身在集成redis時的一些想法。面試
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
/* 操做k-v都是字符串的 */ @Autowired StringRedisTemplate stringRedisTemplet; /* 操做k-v都是對象的 */ @Autowired RedisTemplate redisTemplate;
redis的包中提供了兩個能夠操做方法,根據不一樣類型的值相對應選擇。
兩個操做方法對應的redis操做都是相同的redis
stringRedisTemplet.opsForValue() // 字符串 stringRedisTemplet.opsForList() // 列表 stringRedisTemplet.opsForSet() // 集合 stringRedisTemplet.opsForHash() // 哈希 stringRedisTemplet.opsForZSet() // 有序集合
在StringRedisTemplet中,默認都是存儲字符串的形式;在RedisTemplet中,值能夠是某個對象,而redis默認把對象序列化後存儲在redis中(因此存放的對象默認狀況下須要序列化)spring
若是須要更改數據的存儲方式,如採用json來存儲在redis中,而不是以序列化後的形式。json
1)本身建立一個RedisTemplate實例,在該實例中本身定義json的序列化格式(org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer)springboot
// 這裏傳入的是employee對象(employee 要求能夠序列化) Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
2)把定義的格式放進本身定義的RedisTemplate實例中性能優化
RedisTemplate<Object,Employee> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); // 定義格式 Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class); // 放入RedisTemplate實例中 template.setDefaultSerializer(jackson2JsonRedisSerializer);
參考代碼:架構
@Bean public RedisTemplate<Object,Employee> employeeRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException{ RedisTemplate<Object,Employee> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class); template.setDefaultSerializer(jackson2JsonRedisSerializer); return template; }
原理:併發
@Configuration @ConditionalOnClass({RedisOperations.class}) @EnableConfigurationProperties({RedisProperties.class}) @Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class}) public class RedisAutoConfiguration { public RedisAutoConfiguration() { } @Bean @ConditionalOnMissingBean( name = {"redisTemplate"} ) // 在容器當前沒有redisTemplate時運行 public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean @ConditionalOnMissingBean // 在容器當前沒有stringRedisTemplate時運行 public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } }
若是你本身定義了RedisTemplate後並添加@Bean註解,(要在配置類中定義),那麼默認的RedisTemplate就不會被添加到容器中,運行的就是本身定義的ReidsTemplate實例,而你在實例中本身定義了序列化格式,因此就會以你採用的格式定義存放在redis中的對象。分佈式
springboot默認提供基於註解的緩衝,只要在主程序類(xxxApplication)標註@EnableCaching,緩衝註解有spring-boot
@Cachingable、@CachingEvict、@CachingPut,而且該緩衝默認使用的是ConcurrentHashMapCacheManager
當引入redis的starter後,容器中保存的是RedisCacheManager ,RedisCacheManager建立RedisCache做爲緩衝組件,RedisCache經過操縱redis緩衝數據
在此我向你們推薦一個架構學習交流羣。交流學習羣號:478030634 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
在SpringBoot中,若是要修改序列化機制,能夠直接創建一個配置類,在配置類中自定義CacheManager,在CacheManager中能夠自定義序列化的規則,默認的序列化規則是採用jdk的序列化
注:在SpringBoot 1.5.6 和SpringBoot 2.0.5 的版本中自定義CacheManager存在差別
參考代碼:
// springboot 1.x的版本 public RedisCacheManager employeeCacheManager(RedisConnectionFactory redisConnectionFactory){ // 一、自定義RedisTemplate RedisTemplate<Object,Employee> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer<Employee> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class); template.setDefaultSerializer(jackson2JsonRedisSerializer); // 二、自定義RedisCacheManager RedisCacheManager cacheManager = new RedisCacheManager(template); cacheManager.setUsePrefix(true); // 會將CacheName做爲key的前綴 return cacheManager; } // springboot 2.x的版本 /** * serializeKeysWith() 修改key的序列化規則,這裏採用的是StringRedisSerializer() * serializeValuesWith() 修改value的序列化規則,這裏採用的是 Jackson2JsonRedisSerializer<Employee>(Employee.class) * @param factory * @return */ @Bean public RedisCacheManager employeeCacheManager(RedisConnectionFactory redisConnectionFactory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() . serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<Employee>(Employee.class))); RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build(); return cacheManager; }
tip:能夠經過查看各版本的org.springframework.data.redis.cache.RedisCacheConfiguration去自定義CacheManager.
由於不一樣版本的SpringBoot對應的Redis版本也是不一樣的,因此要重寫時能夠查看官方是怎麼定義CacheManager,才知道怎樣去自定義CacheManager。
你們以爲文章對你仍是有一點點幫助的,你們能夠點擊下方二維碼進行關注。 《 Java爛豬皮 》 公衆號聊的不單單是Java技術知識,還有面試等乾貨,後期還有大量架構乾貨。你們一塊兒關注吧!關注爛豬皮,你會了解的更多..............