精通SpringBoot——第七篇:整合Redis實現快取
阿新 • • 發佈:2018-11-21
專案中用到快取是很常見的事情, 快取能夠提升系統訪問的速度,減輕對資料庫的壓力等好處。今天我們來講講怎麼在spring boot 中整合redis 實現對資料庫查詢結果的快取。
首先第一步要做的就是在pom.xml檔案新增spring-boot-starter-data-redis。
要整合快取,必不可少的就是我們要繼承一個父類CachingConfigurerSupport。我們先看看這個類的原始碼
public class CachingConfigurerSupport implements CachingConfigurer { // Spring's central cache manage SPI , @Override @Nullable public CacheManager cacheManager() { return null; } //key的生成策略 @Override @Nullable public KeyGenerator keyGenerator() { return null; } //Determine the Cache instance(s) to use for an intercepted method invocation. @Override @Nullable public CacheResolver cacheResolver() { return null; } //快取錯誤處理 @Override @Nullable public CacheErrorHandler errorHandler() { return null; } }
RedisConfig類
@Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(listenerAdapter, new PatternTopic("chat")); return container; } @Bean MessageListenerAdapter listenerAdapter(Receiver receiver) { return new MessageListenerAdapter(receiver, "receiveMessage"); } @Bean Receiver receiver(CountDownLatch latch) { return new Receiver(latch); } @Bean CountDownLatch latch() { return new CountDownLatch(1); } public class Receiver { private CountDownLatch latch; @Autowired public Receiver(CountDownLatch latch) { this.latch = latch; } public void receiveMessage(String message) { latch.countDown(); } } @Bean public KeyGenerator myKeyGenerator() { return new KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(JSON.toJSONString(obj)); } return sb.toString(); } }; } /** * @param redisConnectionFactory * @return * @// TODO: 2018/4/27 redis fastjson序列化 */ @Bean @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); //使用fastjson序列化 FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); // 全域性開啟AutoType,不建議使用 // ParserConfig.getGlobalInstance().setAutoTypeSupport(true); // 建議使用這種方式,小範圍指定白名單 ParserConfig.getGlobalInstance().addAccept("com.developlee.models."); // value值的序列化採用fastJsonRedisSerializer template.setValueSerializer(fastJsonRedisSerializer); template.setHashValueSerializer(fastJsonRedisSerializer); // key的序列化採用StringRedisSerializer template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean @ConditionalOnMissingBean(StringRedisTemplate.class) public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } /** * @return * @// TODO: 2018/4/27 設定redis 快取時間 5 分鐘 */ @Bean public RedisCacheConfiguration redisCacheConfiguration() { FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig(); configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(fastJsonRedisSerializer)).entryTtl(Duration.ofMinutes(5)); return configuration; } }
這段程式碼中,重點關注物件是RedisTemplate 和StringRedisTemplate還有RedisMessageListenerContainer,RedisTemplate和StringRedisTemplate設定了一些序列化的引數和指定序列化的範圍(主要為了防止黑客利用Redis的序列化漏洞),@ConditionalOnMissingBean註解的意思就是如果容器中沒有這個型別Bean就選擇當前Bean。RedisMessageListenerContainer是為Redis訊息偵聽器提供非同步行為的容器,主要處理低層次的監聽、轉換和訊息傳送的細節。
再來看看application.xml我們的配置 , so easy~~
spring:
redis:
database: 0 # Redis資料庫索引(預設為0)
host: 192.168.0.100 # Redis伺服器地址 (預設為127.0.0.1)
port: 6379 # Redis伺服器連線埠 (預設為6379)
password: 123456 # Redis伺服器連線密碼(預設為空)
timeout: 2000 # 連線超時時間(毫秒)
cache:
type: redis
接下來我們就可以使用Redis快取了,在Service層我們用註解@Cacheable來快取查詢的結果。
@Cacheable(value= "orderDetailCache", keyGenerator = "myKeyGenerator", unless = "#result eq null")
public OrderDetailEntity findOrderDetail(OrderDetailEntity orderDetailEntity) {
return orderDetailDao.findEntity(orderDetailEntity);
}
到這裡我們就已經整合了Redis快取了,是不是很簡單的呢?自己多動手嘗試哦!