spring整合redis缓存

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
系统运维管理,不限时长
简介:

如果对spring cache不了解,这边有一篇文章详细的介绍了
http://jinnianshilongnian.iteye.com/blog/2001040
改项目基于maven构建
相关依赖

Xml代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
< dependency >  
     < groupId >org.springframework.data</ groupId >  
     < artifactId >spring-data-redis</ artifactId >  
     < version >1.3.4.RELEASE</ version >  
</ dependency >  
   
< dependency >  
     < groupId >redis.clients</ groupId >  
     < artifactId >jedis</ artifactId >  
     < version >2.5.2</ version >  
</ dependency >  
   
< dependency >  
     < groupId >org.springframework</ groupId >  
     < artifactId >spring-jdbc</ artifactId >  
     < version >3.2.13.RELEASE</ version >  
</ dependency >  
   
<!-- 日志记录依赖包,很多都依赖此包,像log4j,json-lib等等 -->  
< dependency >  
     < groupId >commons-logging</ groupId >  
     < artifactId >commons-logging-api</ artifactId >  
     < version >1.1</ version >  
</ dependency >  
   
<!-- junit 测试包 -->  
< dependency >  
     < groupId >junit</ groupId >  
     < artifactId >junit</ artifactId >  
     < version >4.11</ version >  
     < scope >test</ scope >  
</ dependency >  
   
< dependency >  
     < groupId >org.springframework</ groupId >  
     < artifactId >spring-test</ artifactId >  
     < version >3.2.13.RELEASE</ version >  
     < scope >test</ scope >  
</ dependency >

Spring相关配置
Xml代码  收藏代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<? xml  version = "1.0"  encoding = "UTF-8" ?>  
< beans  xmlns = "http://www.springframework.org/schema/beans"  
     xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"  xmlns:context = "http://www.springframework.org/schema/context"  
     xmlns:cache = "http://www.springframework.org/schema/cache"  xmlns:p = "http://www.springframework.org/schema/p"  
     xmlns:c = "http://www.springframework.org/schema/c"  
     xsi:schemaLocation="  
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd  
         http://www.springframework.org/schema/cache   
         http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"  
     default-lazy-init = "true" >  
   
     < context:property-placeholder  location = "classpath:redis.properties"  />  
       
     <!-- 自动扫描包 -->  
     < context:component-scan  base-package = "com.layou"  />  
   
   
     <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->  
     < cache:annotation-driven  cache-manager = "cacheManager"  />  
   
     <!-- spring自己的换管理器,这里定义了两个缓存位置名称 ,既注解中的value -->  
     < bean  id = "cacheManager"  class = "org.springframework.cache.support.SimpleCacheManager" >  
         < property  name = "caches" >  
             < set >  
                 < bean  class = "com.layou.RedisCache" >  
                     < property  name = "redisTemplate"  ref = "redisTemplate"  />  
                     < property  name = "name"  value = "default"  />  
                 </ bean >  
             </ set >  
         </ property >  
     </ bean >  
   
     <!-- redis 相关配置 -->  
     < bean  id = "poolConfig"  class = "redis.clients.jedis.JedisPoolConfig" >  
         < property  name = "maxIdle"  value = "${redis.pool.maxIdle}"  />  
         < property  name = "maxTotal"  value = "${redis.pool.maxActive}"  />  
         < property  name = "maxWaitMillis"  value = "${redis.pool.maxWait}"  />  
         < property  name = "testOnBorrow"  value = "${redis.pool.testOnBorrow}"  />  
     </ bean >  
   
     < bean  id = "connectionFactory"  
         class = "org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >  
         < property  name = "hostName"  value = "${redis.host}"  />  
         < property  name = "port"  value = "${redis.port}"  />  
         < property  name = "password"  value = "${redis.password}"  />  
         < property  name = "timeout"  value = "${redis.timeout}"  />  
         < property  name = "usePool"  value = "true"  />  
         < property  name = "poolConfig"  ref = "poolConfig"  />  
     </ bean >  
   
     < bean  id = "redisTemplate"  class = "org.springframework.data.redis.core.RedisTemplate" >  
         < property  name = "connectionFactory"  ref = "connectionFactory"  />  
     </ bean >  
</ beans >

redis相关配置
Java代码  收藏代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#redis.host=localhost  
redis.host=192.168.71.145  
redis.port=6379  
redis.password=  
#客户端超时时间单位是毫秒  
redis.timeout=100000  
   
#最大连接数  
redis.pool.maxActive=500    
#最大能够保持idel状态的对象数    
redis.pool.maxIdle=200    
#最大建立连接等待时间    
redis.pool.maxWait=2000    
#当调用borrow Object方法时,是否进行有效性检查    
redis.pool.testOnBorrow=true

首先,通过自己实现Cache接口来实现对redis的相关操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package  com.layou;  
   
import  java.io.ByteArrayInputStream;  
import  java.io.ByteArrayOutputStream;  
import  java.io.IOException;  
import  java.io.ObjectInputStream;  
import  java.io.ObjectOutputStream;  
   
import  org.springframework.cache.Cache;  
import  org.springframework.cache.support.SimpleValueWrapper;  
import  org.springframework.dao.DataAccessException;  
import  org.springframework.data.redis.connection.RedisConnection;  
import  org.springframework.data.redis.core.RedisCallback;  
import  org.springframework.data.redis.core.RedisTemplate;  
   
public  class  RedisCache  implements  Cache {  
   
     private  RedisTemplate<String, Object> redisTemplate;  
     private  String name;  
   
     public  RedisTemplate<String, Object> getRedisTemplate() {  
         return  redisTemplate;  
     }  
   
     public  void  setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {  
         this .redisTemplate = redisTemplate;  
     }  
   
     public  void  setName(String name) {  
         this .name = name;  
     }  
   
     @Override  
     public  String getName() {  
         return  this .name;  
     }  
   
     @Override  
     public  Object getNativeCache() {  
         return  this .redisTemplate;  
     }  
   
     @Override  
     public  ValueWrapper get(Object key) {  
         final  String keyf = (String) key;  
         Object object =  null ;  
         object = redisTemplate.execute( new  RedisCallback<Object>() {  
             public  Object doInRedis(RedisConnection connection)  throws  DataAccessException {  
   
                 byte [] key = keyf.getBytes();  
                 byte [] value = connection.get(key);  
                 if  (value ==  null ) {  
                     return  null ;  
                 }  
                 return  toObject(value);  
   
             }  
         });  
         return  (object !=  null  new  SimpleValueWrapper(object) :  null );  
     }  
   
     @Override  
     public  void  put(Object key, Object value) {  
         final  String keyf = (String) key;  
         final  Object valuef = value;  
         final  long  liveTime =  86400 ;  
   
         redisTemplate.execute( new  RedisCallback<Long>() {  
             public  Long doInRedis(RedisConnection connection)  throws  DataAccessException {  
                 byte [] keyb = keyf.getBytes();  
                 byte [] valueb = toByteArray(valuef);  
                 connection.set(keyb, valueb);  
                 if  (liveTime >  0 ) {  
                     connection.expire(keyb, liveTime);  
                 }  
                 return  1L;  
             }  
         });  
     }  
   
     @Override  
     public  void  evict(Object key) {  
         final  String keyf = (String) key;  
         redisTemplate.execute( new  RedisCallback<Long>() {  
             public  Long doInRedis(RedisConnection connection)  throws  DataAccessException {  
                 return  connection.del(keyf.getBytes());  
             }  
         });  
     }  
   
     @Override  
     public  void  clear() {  
         redisTemplate.execute( new  RedisCallback<String>() {  
             public  String doInRedis(RedisConnection connection)  throws  DataAccessException {  
                 connection.flushDb();  
                 return  "ok" ;  
             }  
         });  
     }  
   
     /** 
      * 描述 : <Object转byte[]>. <br> 
      * <p> 
      * <使用方法说明> 
      * </p> 
      *  
      * @param obj 
      * @return 
      */  
     private  byte [] toByteArray(Object obj) {  
         byte [] bytes =  null ;  
         ByteArrayOutputStream bos =  new  ByteArrayOutputStream();  
         try  {  
             ObjectOutputStream oos =  new  ObjectOutputStream(bos);  
             oos.writeObject(obj);  
             oos.flush();  
             bytes = bos.toByteArray();  
             oos.close();  
             bos.close();  
         catch  (IOException ex) {  
             ex.printStackTrace();  
         }  
         return  bytes;  
     }  
   
     /** 
      * 描述 : <byte[]转Object>. <br> 
      * <p> 
      * <使用方法说明> 
      * </p> 
      *  
      * @param bytes 
      * @return 
      */  
     private  Object toObject( byte [] bytes) {  
         Object obj =  null ;  
         try  {  
             ByteArrayInputStream bis =  new  ByteArrayInputStream(bytes);  
             ObjectInputStream ois =  new  ObjectInputStream(bis);  
             obj = ois.readObject();  
             ois.close();  
             bis.close();  
         catch  (IOException ex) {  
             ex.printStackTrace();  
         catch  (ClassNotFoundException ex) {  
             ex.printStackTrace();  
         }  
         return  obj;  
     }  
}

使用junit进行测试

  1. package com.layou;  

  2.   

  3. import org.junit.Before;  

  4. import org.junit.Test;  

  5. import org.springframework.beans.factory.annotation.Autowired;  

  6. import org.springframework.cache.CacheManager;  

  7. import org.springframework.test.context.ContextConfiguration;  

  8. import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;  

  9.   

  10. @ContextConfiguration(locations = {"classpath:applicationContext-cache-redis.xml"})  

  11. public class RedisTest extends AbstractJUnit4SpringContextTests {  

  12.     private RedisCache cache;  

  13.     @Autowired  

  14.     private CacheManager manager;  

  15.       

  16.     @Before  

  17.     public void before() {  

  18.         cache = (RedisCache) manager.getCache("default");  

  19.     }  

  20.       

  21.     @Test  

  22.     public void testAdd() throws Exception {  

  23.         cache.put("test"1);  

  24.     }  

  25.       

  26.     @Test  

  27.     public void testGet() throws Exception {  

  28.         System.out.println(cache.get("test").get());  

  29.     }  

  30.       

  31.     @Test  

  32.     public void testEvict() throws Exception {  

  33.         cache.evict("test");  

  34.     }  

  35.       

  36.     @Test  

  37.     public void testClear() throws Exception {  

  38.         cache.clear();  

  39.     }  

  40. }

在实际项目中,多是通过Spring的注解完成相关操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package  com.layou;  
   
import  org.springframework.cache.annotation.CacheEvict;  
import  org.springframework.cache.annotation.Cacheable;  
import  org.springframework.stereotype.Service;  
   
@Service  
public  class  RedisAnnotation {  
       
     /** 
      * 第一次查询会到数据库中差寻,第二次就会从缓存中取 
      * #id代表使用参数id 
      * 一定要放在spring容器中管理,不然拦截不到 
      * @param id 
      * @return 
      */  
     @Cacheable (key= "'name' + #id" , value= "default" )  
     public  String getNameById( int  id) {  
         //TODO 进行数据库查询并返回查询数据库内容  
         System.out.println( "查询数据库" );  
         return  ""  + id;  
     }  
       
     /** 
      * 从缓存中删除 
      * @param id 
      */  
     @CacheEvict (key= "'name' + #id" , value= "default" )  
     public  void  deleteById( int  id) {  
         System.out.println( "数据库删除" );  
     }  
}

使用junit进行相关测试










1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package  com.layou;  
   
import  org.junit.Test;  
import  org.springframework.beans.factory.annotation.Autowired;  
import  org.springframework.test.context.ContextConfiguration;  
import  org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;  
   
@ContextConfiguration (locations = { "classpath:applicationContext-cache-redis.xml" })  
public  class  RedisAnnotationTest  extends  AbstractJUnit4SpringContextTests {  
     @Autowired  
     private  RedisAnnotation redis;  
       
     @Test  
     public  void  testQuery() {  
         //第二次查询的时候就会从缓存中取  
         System.out.println(redis.getNameById( 1 ));  
     }  
       
     @Test  
     public  void  testDelete() {  
         redis.deleteById( 1 );  
     }  
}   











本文转自yunlielai51CTO博客,原文链接:http://blog.51cto.com/4925054/1741066 ,如需转载请自行联系原作者



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
184 85
|
24天前
|
存储 缓存 NoSQL
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
|
24天前
|
缓存 NoSQL 关系型数据库
云端问道21期实操教学-应对高并发,利用云数据库 Tair(兼容 Redis®)缓存实现极速响应
本文介绍了如何通过云端问道21期实操教学,利用云数据库 Tair(兼容 Redis®)缓存实现高并发场景下的极速响应。主要内容分为四部分:方案概览、部署准备、一键部署和完成及清理。方案概览中,展示了如何使用 Redis 提升业务性能,降低响应时间;部署准备介绍了账号注册与充值步骤;一键部署详细讲解了创建 ECS、RDS 和 Redis 实例的过程;最后,通过对比测试验证了 Redis 缓存的有效性,并指导用户清理资源以避免额外费用。
|
2月前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文详细探讨了分布式系统和缓存应用中的经典问题——缓存穿透。缓存穿透是指用户请求的数据在缓存和数据库中都不存在,导致大量请求直接落到数据库上,可能引发数据库崩溃或性能下降。文章介绍了几种有效的解决方案,包括接口层增加校验、缓存空值、使用布隆过滤器、优化数据库查询以及加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统的影响,提升系统的稳定性和性能。
|
2月前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
192 5
|
2月前
|
缓存 NoSQL Java
Spring Boot中的分布式缓存方案
Spring Boot提供了简便的方式来集成和使用分布式缓存。通过Redis和Memcached等缓存方案,可以显著提升应用的性能和扩展性。合理配置和优化缓存策略,可以有效避免常见的缓存问题,保证系统的稳定性和高效运行。
71 3
|
2月前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
121 4
|
4月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
98 6
|
3月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
3月前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构