javascript
SpringBoot集成Redis--配置自定义的RedisCacheManager
2019獨角獸企業重金招聘Python工程師標準>>>
配置自定義的RedisCacheManager--1自定義鍵生成規則
默認的鍵生成器
當不指定緩存的key時,SpringBoot會使用SimpleKeyGenerator生成key。
SimpleKeyGenerator
SimpleKey
查看源碼可以發現,它是使用方法參數組合生成的一個key。
通過SpEL自定義鍵生成規則
諸如下面紅框的代碼,SpEL實際上可以寫非常復雜的生成規則。
自定義鍵生成器
在 @Configuration?標注的類中,可以根據自己設計的規則自定義鍵生成器。
自定義鍵生成器代碼
/*** 新的鍵生成規則*/@Bean @Override public KeyGenerator keyGenerator() {return new KeyGenerator(){public Object generate(Object target, Method method, Object... 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();}};}代碼分析
上面自定義的鍵生成器鍵的生成規則是:包名+方法名+參數列表。
配置自定義的RedisCacheManager--2創建RedisTemplate模板時自定義序列化器
RedisTemplate默認提供的序列化器
RedisSerializer redis序列化的接口類
OxmSerializer xml到object的序列化/反序列化
StringRedisSerializer string字符串的序列化/反序列化
JacksonJsonRedisSerializer json到object的序列化/反序列化
Jackson2JsonRedisSerializer json到object的序列化/反序列化
JdkSerializationRedisSerializer java對象的序列化/反序列化
RedisTemplate默認使用的是JdkSerializationRedisSerializer
常見序列化方式的特點
JdkSerializationRedisSerializer:JDK自帶的序列化方式、存儲的字符串內容在序列化的情況下偏長,會占用過多的內存
OxmSerializer:序列化的時間相對較長
Jackson2JsonRedisSerializer:json數據格式、序列化時間和序列化之后內容的長度都要優于前兩種
自定義序列化器--使用Jackson2JsonRedisSerializer
代碼
/*** RedisTemplate 使用 Jackson2JsonRedisSerializer 作為序列化器* @return*/@Bean public RedisTemplate<String, String> redisTemplate() {StringRedisTemplate redisTemplate = new StringRedisTemplate(jedisConnectionFactory);Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}Jackson2JsonRedisSerializer的序列化器需要引入Jackson的依賴
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.6.7</version></dependency>配置自定義的RedisCacheManager--3示例代碼
總體項目結構
POM文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ding.data</groupId><artifactId>RedisCacheCase</artifactId><version>0.0.1-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><boot.version>1.3.5.RELEASE</boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>${boot.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>${boot.version}</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId><version>${boot.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId><version>${boot.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.6.7</version></dependency><!-- <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>19.0</version></dependency> --></dependencies></project>配置文件application.yml
????
spring:cache:#緩存名稱#cache-names: guavaDemo#緩存最大數量500條, 緩存失效時間 6個小時#guava.spec: maximumSize=500,expireAfterWrite=360m# REDIS (RedisProperties) redis :host : localhost # server host port : 6379 # connection port password : 123database : 1pool.max-idle : 8 # pool settings ... pool.min-idle : 1pool.max-active : 8 pool.max-wait : -1?
主啟動類
package com.ding.data;import java.text.SimpleDateFormat;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import com.ding.data.cache.DataCache;/*** 是Spring Boot項目的核心注解,主要是開啟自動配置*/@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan@RestController// 開啟緩存@EnableCachingpublic class RedisCacheCase {@Autowiredprivate DataCache dataCache;public static void main(String[] args) {SpringApplication.run(RedisCacheCase.class, args);}@RequestMapping("/put")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return sdf.format(new Date()) + " : value is " + dataCache.put(id, value) ;}@RequestMapping("/get")public String query(Long id){SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return sdf.format(new Date()) + " : value is " +dataCache.query(id) ;}@RequestMapping("/remove")public String remove(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");dataCache.remove(id) ;return sdf.format(new Date()) + " : success " ;}}配置類代碼
package com.ding.data.config;import java.lang.reflect.Method;import org.springframework.beans.factory.annotation.Autowired;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.jedis.JedisConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;@Configurationpublic class MyRedisCacheConfig extends CachingConfigurerSupport{@Autowiredprivate JedisConnectionFactory jedisConnectionFactory;@Beanpublic CacheManager cacheManager() {RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());redisCacheManager.setDefaultExpiration(86400);return redisCacheManager;}/*** RedisTemplate 使用 Jackson2JsonRedisSerializer 作為序列化器* @return*/@Bean public RedisTemplate<String, String> redisTemplate() {StringRedisTemplate redisTemplate = new StringRedisTemplate(jedisConnectionFactory);Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);redisTemplate.afterPropertiesSet();return redisTemplate;}/*** 新的鍵生成規則*/@Bean @Override public KeyGenerator keyGenerator() {return new KeyGenerator(){public Object generate(Object target, Method method, Object... 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();}};}}業務層代碼
package com.ding.data.cache;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.annotation.PostConstruct;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Component;@Componentpublic class DataCache {private Map<Long, String> dataMap = new HashMap<Long, String>();/*** 初始化*/@PostConstructpublic void init() {dataMap.put(1L, "張三");dataMap.put(2L, "李四");dataMap.put(3L, "王五");}/*** 查詢* 如果數據沒有緩存,那么從dataMap里面獲取,如果緩存了,* 那么從redisDemo里面獲取* 并且將緩存的數據存入到 redisDemo里面* 其中key 為 #id+dataMap*/// @Cacheable(value="redisDemo" ,key="#id + 'dataMap'")@Cacheable(value="redisDemo")public String query(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : query id is " + id);return dataMap.get(id);}/*** 插入 或者更新* 插入或更新數據到dataMap中* 并且緩存到 redisDemo中* 如果存在了那么更新緩存中的值* 其中key 為 #id+dataMap*/// @CachePut(value="redisDemo" ,key="#id + 'dataMap'")@CachePut(value="redisDemo")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id);dataMap.put(id, value);// data persistencereturn value;}/*** 刪除* 刪除dataMap里面的數據* 并且刪除緩存redisDemo中的數據* 其中key 為 #id+dataMap*/// @CacheEvict(value="redisDemo" , key="#id + 'dataMap'")@CacheEvict(value="redisDemo")public void remove(Long id) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : remove id is "+ id + " data");dataMap.remove(id);// data remove }}測試
依次訪問:
http://localhost:8080/get?id=1
http://localhost:8080/get?id=2
http://localhost:8080/put?id=1&value=meixi
http://localhost:8080/put?id=1&value=neimaer
http://localhost:8080/put?id=1&value=cluo
查看Redis內存的內容,如下(因為Redis的database參數用的1,所以用的是Redis中的db1庫)
與代碼的邏輯是相符的,但是出現了新的問題,除了 @Cacheable?注解的方法仍然起到緩存的作用,其他的緩存方法實際上沒起作用。這主要是因為現在緩存鍵生成的規則不具備重復利用性,實際項目需要根據需求對鍵生成規則進行修改的。
代碼改造一下:使 @CachePut?注解的方法也能起作用
新增一個類MyKeyGenerator
package com.ding.data.config;import java.lang.reflect.Method;import org.springframework.cache.interceptor.KeyGenerator;import org.springframework.stereotype.Component;@Componentpublic class MyKeyGenerator implements KeyGenerator{public Object generate(Object target, Method method, Object... params) {StringBuilder sb = new StringBuilder();sb.append(target.getClass().getName());sb.append("::" + "query" + ":" + params[0].toString());return sb.toString();}}DataCache類中?@CachePut?標注的方法改造如下
/*** 插入 或者更新* 插入或更新數據到dataMap中* 并且緩存到 redisDemo中* 如果存在了那么更新緩存中的值* 其中key 為 #id+dataMap*/// @CachePut(value="redisDemo" ,key="#id + 'dataMap'")@CachePut(value="redisDemo",keyGenerator="myKeyGenerator")public String put(Long id, String value) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()) + " : add data ,id is "+ id);dataMap.put(id, value);// data persistencereturn value;}keyGenerator="myKeyGenerator"啥意思
意思就是說明這個方法的鍵生成規則采用myKeyGenerator這個類
再次測試(先將剛才測試的數據都清空)
依次訪問:
http://localhost:8080/get?id=1
http://localhost:8080/put?id=1&value=meixi
查看Redis數據庫中的數據
可見改造后@CachePut?標注的方法也起作用了。
但是現在代碼仍然太“死性”,無法應用于實際項目。要想應用于實際項目,還需要根據具體需求進行設計。
轉載于:https://my.oschina.net/u/3866531/blog/1858465
總結
以上是生活随笔為你收集整理的SpringBoot集成Redis--配置自定义的RedisCacheManager的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mybaitis 通过Mapping 实
- 下一篇: 【技术短文】基于深度负相关学习的人群计数