Spring 中使用redis缓存方法记录

背景

  在平时项目中,可能会有某个条件的查询,会多次进到db里面去查,这样就会重复的查询相同的数据,但是我们的数据又不是需要更改及显示的,这时候就可以用到

  方法的缓存了。例如在我们调用微信小程序时,需要获取access_token,并且其有效时间为7200秒,过期后再次获取,我们就可以把获取access_token的方法作为

  缓存。以下为我实现的过程记录。

1、重写 RedisSerializer 中的 serialize 和 deserialize

 1 public class GenericFastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
 2     public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
 3     public GenericFastJson2JsonRedisSerializer() {
 4         super();
 5     }
 6    @Override
 7     public byte[] serialize(T t) throws SerializationException {
 8         if (t == null) {
 9             return new byte[0];
10         }
11        FastJsonWraper<T> wraperSet =new FastJsonWraper<>(t);
12        return JSON.toJSONString(wraperSet, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
13    }
14     @Override
15     public T deserialize(byte[] bytes) throws SerializationException {
16         if (bytes == null || bytes.length <= 0) {
17             return null;
18         }
19         String deserializeStr = new String(bytes, DEFAULT_CHARSET);
20         FastJsonWraper<T> wraperGet=JSON.parseObject(deserializeStr,FastJsonWraper.class);
21         return wraperGet.getValue();
22     }
23 }

重写RedisSerializer

2、实现缓存的获取和设置

  1 public class RedisCache implements Cache {
  2
  3     private Logger logger = Logger.getLogger(RedisCache.class);
  4     private RedisTemplate<String, Object> redisTemplate;
  5
  6     private String name;
  7
  8     private String resultType;
  9
 10     private long expireInSencods;
 11
 12     public static final String KEY_PREFIX = "wx:";
 13
 14
 15     @Override
 16     public Object getNativeCache() {
 17         return this.redisTemplate;
 18     }
 19
 20
 21     @Override
 22     public ValueWrapper get(Object key) {
 23         if (logger.isDebugEnabled()) {
 24             logger.debug("------缓存获取-------" + key.toString());
 25         }
 26         final String keyf = KEY_PREFIX + key.toString();
 27         Object object = null;
 28         object = redisTemplate.execute(new RedisCallback<Object>() {
 29             @Override
 30             public Object doInRedis(RedisConnection connection) throws DataAccessException {
 31                 byte[] key = keyf.getBytes();
 32                 byte[] value = connection.get(key);
 33                 if (value == null) {
 34                     if (logger.isDebugEnabled()) {
 35                         logger.debug("------缓存不存在-------");
 36                     }
 37                     return null;
 38                 }
 39                 try {
 40                     Class<?> class1 = null;
 41                     if (StringUtils.isNotEmpty(resultType)) {
 42                         class1 = Class.forName(resultType);
 43                     } else {
 44                         class1 = String.class;
 45                     }
 46                     String resultJson = new String(value, Charset.forName("utf-8"));
 47                     Object result = JSONObject.parseObject(resultJson, class1);
 48                     return result;
 49                 } catch (ClassNotFoundException e) {
 50                     e.printStackTrace();
 51                 }
 52                 return null;
 53             }
 54         });
 55         ValueWrapper obj = (object != null ? new SimpleValueWrapper(object) : null);
 56         if (logger.isDebugEnabled()) {
 57             logger.debug("------获取到内容-------" + obj);
 58         }
 59         return obj;
 60     }
 61
 62
 63     @Override
 64     public <T> T get(Object key, Class<T> type) {
 65         // TODO Auto-generated method stub
 66         return null;
 67     }
 68
 69
 70     @Override
 71     public <T> T get(Object key, Callable<T> valueLoader) {
 72         // TODO Auto-generated method stub
 73         return null;
 74     }
 75
 76
 77     @Override
 78     public void put(Object key, Object value) {
 79         if (logger.isDebugEnabled()) {
 80             logger.debug("-------加入缓存------");
 81             logger.debug("key----:" + key);
 82             logger.debug("key----:" + value);
 83         }
 84         final String keyString = KEY_PREFIX + key.toString();
 85         final Object valuef = value;
 86         redisTemplate.execute(new RedisCallback<Long>() {
 87             @Override
 88             public Long doInRedis(RedisConnection connection) throws DataAccessException {
 89                 byte[] keyb = keyString.getBytes();
 90                 String valuejson = JSONObject.toJSONString(valuef);
 91                 byte[] valueb = valuejson.getBytes(Charset.forName("utf-8"));
 92                 connection.set(keyb, valueb);
 93                 if (expireInSencods > 0) {
 94                     connection.expire(keyb, expireInSencods);
 95                 }
 96                 return 1L;
 97             }
 98         });
 99     }
100
101
102     @Override
103     public ValueWrapper putIfAbsent(Object key, Object value) {
104         // TODO Auto-generated method stub
105         return null;
106     }
107
108
109     @Override
110     public void evict(Object key) {
111         if (logger.isDebugEnabled()) {
112             logger.debug("-------緩存刪除------");
113         }
114         final String keyf = KEY_PREFIX + key.toString();
115         redisTemplate.execute(new RedisCallback<Long>() {
116             @Override
117             public Long doInRedis(RedisConnection connection) throws DataAccessException {
118                 return connection.del(keyf.getBytes());
119             }
120
121         });
122     }
123
124
125     @Override
126     public void clear() {
127         if (logger.isDebugEnabled()) {
128             logger.debug("-------緩存清理------");
129         }
130         redisTemplate.execute(new RedisCallback<String>() {
131             @Override
132             public String doInRedis(RedisConnection connection) throws DataAccessException {
133                 connection.flushDb();
134                 return "ok";
135             }
136         });
137     }
138
139     /**
140      * @return redisTemplate
141      */
142     public RedisTemplate<String, Object> getRedisTemplate() {
143         return redisTemplate;
144     }
145
146     /**
147      * @param redisTemplate the redisTemplate to set
148      */
149     public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
150         this.redisTemplate = redisTemplate;
151     }
152
153     /**
154      * @param name the name to set
155      */
156     public void setName(String name) {
157         this.name = name;
158     }
159
160     /**
161      * @return name
162      */
163     @Override
164     public String getName() {
165         return name;
166     }
167
168     /**
169      * @return resultType
170      */
171     public String getResultType() {
172         return resultType;
173     }
174
175     /**
176      * @param resultType the resultType to set
177      */
178     public void setResultType(String resultType) {
179         this.resultType = resultType;
180     }
181
182     /**
183      * @return expireInSencods
184      */
185     public long getExpireInSencods() {
186         return expireInSencods;
187     }
188
189     /**
190      * @param expireInSencods the expireInSencods to set
191      */
192     public void setExpireInSencods(long expireInSencods) {
193         this.expireInSencods = expireInSencods;
194     }
195
196 }

3、在spring-redis.xml中配置 spring mvc自定义缓存,bean 中的class为我们缓存实现类的包路径,属性均为缓存实现类中的属性。

 1 <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
 2         <property name="caches">
 3             <set>
 4                 <bean class="xxxx.xxx.xxx.RedisCache">
 5                     <property name="redisTemplate" ref="redisTemplate"/>
 6                     <property name="name" value="wechatapp"/>
 7                     <property name="expireInSencods" value="7200"/>
 8                     <property name="resultType"
 9                               value="xxxx.xx.xxx.xx"/>
10                 </bean>
11             </set>
12         </property>
13     </bean>

Spring mvc 自定义缓存

4、在代码中使用缓存,使用注解 @Cacheable,其中缓存名字cacheNames需要与我们spring redis中配置bean的<property name="name" value="xxx"/>对应起来

    @Cacheable(cacheNames = CACHE_NAME,key = "#appid+‘:‘+#secret",unless = "#result == null")
    @Override
    public WeChatAppResponseDto getAccessToken(String appid, String secret) {

    }

代码中的使用

然后执行代码可以发现,在第一次进入的时候,进入方法内部,然后返回结果,再次访问就没有进入方法内部了,可以打断点在缓存获取方法中查看,后面的都直接在缓存中获取了。其实通过引入的相关依赖也可以看出来,该注解功能是利用AOP来实现的。

原文地址:https://www.cnblogs.com/rolayblog/p/11176270.html

时间: 2024-10-08 10:49:44

Spring 中使用redis缓存方法记录的相关文章

linux中的redis缓存服务器

Linux中的Redis缓存服务器 一.Redis基础部分: 1.redis介绍与安装比mysql快10倍以上 *****************redis适用场合**************** 1.取最新N个数据的操作 2.排行榜应用,取TOP N 操作 3.需要精确设定过期时间的应用 4.计数器应用 5.Uniq操作,获取某段时间所有数据排重值 6.实时系统,反垃圾系统7.Pub/Sub构建实时消息系统 7.Pub/Sub构建实时消息系统8.构建队列系统 9.缓存 ============

spring boot 使用 redis 缓存

spring boot redis 使用 1 Redis:Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库.Redis 与其他 key - value 缓存产品有以下三个特点:Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用.Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储.Redis支持数据的备份,即master-slave模式的数据备份. spr

Spring Boot自定义Redis缓存配置,保存value格式JSON字符串

Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 package springboot01cache.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; im

Spring优雅整合Redis缓存

“小明,多系统的session共享,怎么处理?”“Redis缓存啊!” “小明,我想实现一个简单的消息队列?”“Redis缓存啊!” “小明,分布式锁这玩意有什么方案?”“Redis缓存啊!” “小明,公司系统响应如蜗牛,咋整?”“Redis缓存啊!” 本着研究的精神,我们来分析下小明的第四个问题. 准备: Idea2019.03/Gradle6.0.1/Maven3.6.3/JDK11.0.4/Lombok0.28/SpringBoot2.2.4RELEASE/mybatisPlus3.3.0

spring boot集成redis缓存

spring boot项目中使用redis作为缓存. 先创建spring boot的maven工程,在pom.xml中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.3.RELEASE</version> </depen

spring boot 使用redis缓存

感谢大神分享! https://www.cnblogs.com/gdpuzxs/p/7222309.html (1)pom.xml引入jar包,如下: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> (2)修改项目启动类,增加注解@

Spring中配置log4j的方法

Spring中使用log4j的方便之处 1. 动态的改变记录级别和策略,即修改log4j.properties,不需要重启Web应用,这需要在web.xml中设置一下.2. 把log文件定在 /WEB-INF/logs/ 而不需要写绝对路径.3. 可以把log4j.properties和其他properties一起放在/WEB-INF/ ,而不是Class-Path. web.xml中的设定 在web.xml中的详细设定如下: <context-param> <param-name>

spring中订阅redis键值过期消息通知

1.首先启用redis通知功能(ubuntu下操作):编辑/etc/redis/redis.conf文件,添加或启用以下内容(过期通知): notify-keyspace-events Ex 或者登陆redis-cli之后,输入以下命令: config set notify-keyspace-events Ex 更多通知详见:http://redis.io/topics/notifications#configuration 2.Java Spring中配置监听 接口类: import java

Spring中RestTemplate的使用方法

一.REST在互联网中,我们会通过请求url来对网络上的资源做增删改查等动作,这里的请求包含两部分:动词,主要包括增.删.改.查名词,就是网络中的各种资源传统的非REST风格的请求方式是把动词和名词全都放在url中.例如,对设备的操作可能是这样的:添加设备:http://test/device/add删除设备:http://test/device/delete修改设备:http://test/device/modify查找设备:http://test/device/find这样就存在一个规范的问