java redis 注解_Spring集成Redis使用注解
使用Maven项目,添加jar文件依赖:
1
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3 4.0.0
4 com.luo
5 redis_project
6 0.0.1-SNAPSHOT
7
8
9
10 3.2.8.RELEASE
11
12 4.10
13
14
15
16
17
18 org.springframework
19 spring-core
20 ${spring.version}
21
22
23 org.springframework
24 spring-webmvc
25 ${spring.version}
26
27
28 org.springframework
29 spring-context
30 ${spring.version}
31
32
33 org.springframework
34 spring-context-support
35 ${spring.version}
36
37
38 org.springframework
39 spring-aop
40 ${spring.version}
41
42
43 org.springframework
44 spring-aspects
45 ${spring.version}
46
47
48 org.springframework
49 spring-tx
50 ${spring.version}
51
52
53 org.springframework
54 spring-jdbc
55 ${spring.version}
56
57
58 org.springframework
59 spring-web
60 ${spring.version}
61
62
63
64
65 junit
66 junit
67 ${junit.version}
68 test
69
70
71
72
73 org.springframework
74 spring-test
75 ${spring.version}
76 test
77
78
79
80
81 org.springframework.data
82 spring-data-redis
83 1.6.1.RELEASE
84
85
86 redis.clients
87 jedis
88 2.7.3
89
90
91
92 net.sf.ehcache
93 ehcache-core
94 2.6.6
95
96
97
1 #redis中心2 #绑定的主机地址3 redis.host=127.0.0.1
4 #指定Redis监听端口,默认端口为63795 redis.port=6379
6 #授权密码(本例子没有使用)7 redis.password=123456
8 #最大空闲数:空闲链接数大于maxIdle时,将进行回收9 redis.maxIdle=100
10 #最大连接数:能够同时建立的“最大链接个数”11 redis.maxActive=300
12 #最大等待时间:单位ms13 redis.maxWait=1000
14 #使用连接时,检测连接是否成功15 redis.testOnBorrow=true
16 #当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能17 redis.timeout=10000
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p"
5 xmlns:cache="http://www.springframework.org/schema/cache" xmlns:aop="http://www.springframework.org/schema/aop"
6 xsi:schemaLocation="
7 http://www.springframework.org/schema/beans
8 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
9 http://www.springframework.org/schema/aop
10 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
11 http://www.springframework.org/schema/context
12 http://www.springframework.org/schema/context/spring-context-3.0.xsd
13 http://www.springframework.org/schema/cache
14 http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
15
16
17
18
19
20
21
22
23 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
24
25
26 classpath:properties/*.properties27 28 29 30
31
32 33 34 35 36 37 38
39 40 42 43 44 45 46 47 48 49 50 51 53 54 55 57 58 59 60 61 62 63 64 65 66
67 68 69
70
MethodCacheInterceptor类:
1 packagecom.redis.cache;2
3 importjava.io.Serializable;4 importjava.util.concurrent.TimeUnit;5 importorg.aopalliance.intercept.MethodInterceptor;6 importorg.aopalliance.intercept.MethodInvocation;7 importorg.springframework.data.redis.core.RedisTemplate;8 importorg.springframework.data.redis.core.ValueOperations;9 importorg.springframework.stereotype.Service;10
11 @Service12 public class MethodCacheInterceptor implementsMethodInterceptor {13
14 private RedisTemplateredisTemplate;15 private Long defaultCacheExpireTime = 10l;16
17 public Object invoke(MethodInvocation invocation) throwsThrowable {18 Object value = null;19
20 String targetName =invocation.getThis().getClass().getName();21 String methodName =invocation.getMethod().getName();22
23 Object[] arguments =invocation.getArguments();24 String key =getCacheKey(targetName, methodName, arguments);25
26 try{27
28 if(exists(key)) {29 returngetCache(key);30 }31
32 value =invocation.proceed();33 if (value != null) {34 final String tkey =key;35 final Object tvalue =value;36 new Thread(newRunnable() {37 public voidrun() {38 setCache(tkey, tvalue, defaultCacheExpireTime);39 }40 }).start();41 }42 } catch(Exception e) {43 e.printStackTrace();44 if (value == null) {45 returninvocation.proceed();46 }47 }48 returnvalue;49 }50
51 /**
52 *53 *@paramtargetName54 *@parammethodName55 *@paramarguments56 */
57 privateString getCacheKey(String targetName, String methodName,58 Object[] arguments) {59 StringBuffer sbu = newStringBuffer();60 sbu.append(targetName).append("_").append(methodName);61 if ((arguments != null) && (arguments.length != 0)) {62 for (int i = 0; i < arguments.length; i++) {63 sbu.append("_").append(arguments[i]);64 }65 }66 returnsbu.toString();67 }68
69 /**
70 *71 *@paramkey72 *@return
73 */
74 public boolean exists(finalString key) {75 returnredisTemplate.hasKey(key);76 }77
78 /**
79 *80 *@paramkey81 *@return
82 */
83 public Object getCache(finalString key) {84 Object result = null;85 ValueOperations operations =redisTemplate86 .opsForValue();87 result =operations.get(key);88 returnresult;89 }90
91 /**
92 *93 *@paramkey94 *@paramvalue95 *@return
96 */
97 public boolean setCache(finalString key, Object value, Long expireTime) {98 boolean result = false;99 try{100 ValueOperations operations =redisTemplate101 .opsForValue();102 operations.set(key, value);103 redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);104 result = true;105 } catch(Exception e) {106 e.printStackTrace();107 }108 returnresult;109 }110
111 public voidsetRedisTemplate(112 RedisTemplateredisTemplate) {113 this.redisTemplate =redisTemplate;114 }115 }
使用注解:
1 /*
2 * 文件名:UserServiceImpl.java3 * 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved.4 * 描述: UserServiceImpl.java5 * 修改人:peiyu6 * 修改时间:2016年8月5日7 * 修改内容:新增8 */
9 packagecom.luo.service.impl;10
11 importjava.util.ArrayList;12 importjava.util.List;13
14 importorg.springframework.cache.annotation.CachePut;15 importorg.springframework.cache.annotation.Cacheable;16 importorg.springframework.cache.annotation.Caching;17 importorg.springframework.stereotype.Service;18
19 importcom.luo.redis.anno.UserSaveCache;20 importcom.luo.redis.model.User;21 importcom.luo.service.UserService;22
23 /**
24 *@authorpeiyu25 */
26 @Service27 public class UserServiceImpl implementsUserService {28 //@CachePut(value = "user", key = "'id_'+#user.getId()")
29 /*@Caching(put = {30 @CachePut(value = "user", key = "'user_id_'+#user.id"),31 @CachePut(value = "user", key = "'user_username_'+#user.username"),32 @CachePut(value = "user", key = "'user_email_'+#user.email")33 })*/
34 @UserSaveCache35 publicUser addUser(User user) {36 System.out.println("addUser,@CachePut注解方法被调用啦。。。。。");37 returnuser;38 }39 @Cacheable(value = "user", key = "'id_'+#id") //,key="'user_id_'+#id"
40 publicUser getUserByID(Integer id) {41 System.out.println("@Cacheable注解方法被调用啦。。。。。");42 User user = newUser();43 user.setUsername("zhangsan");44 user.setPassword("123456");45 user.setAge(10);46 user.setId(123);47 user.setEmail("192554785@163.com");48 returnuser;49 }50 @CachePut(value = "user", key = "'users_'+#user.getId()")51 public ListgetUsers(User user) {52 System.out.println("@CachePut注解方法被调用啦。。。。。");53 List users = new ArrayList();54 for (int i = 0; i < 10; i++) {55 User temp = newUser();56 temp.setUsername("username" +i);57 users.add(temp);58 }59 returnusers;60 }61 }
UserSaveCache自定义注解:
1 /*
2 * 文件名:UserSaveCache.java3 * 版权:Copyright 2007-2016 517na Tech. Co. Ltd. All Rights Reserved.4 * 描述: UserSaveCache.java5 * 修改人:peiyu6 * 修改时间:2016年8月5日7 * 修改内容:新增8 */
9 packagecom.luo.redis.anno;10
11 importjava.lang.annotation.ElementType;12 importjava.lang.annotation.Inherited;13 importjava.lang.annotation.Retention;14 importjava.lang.annotation.RetentionPolicy;15 importjava.lang.annotation.Target;16
17 importorg.springframework.cache.annotation.CachePut;18 importorg.springframework.cache.annotation.Caching;19
20 /**
21 *@authorpeiyu22 */
23 @Caching(put ={24 @CachePut(value = "user", key = "'user_id_'+#user.id"),25 @CachePut(value = "user", key = "'user_username_'+#user.username"),26 @CachePut(value = "user", key = "'user_email_'+#user.email")27 })28 @Target({ElementType.METHOD, ElementType.TYPE})29 @Retention(RetentionPolicy.RUNTIME)30 @Inherited31 public @interfaceUserSaveCache {32 }
加载配置文件:
1 packagecom.luo.baseTest;2
3 importorg.junit.runner.RunWith;4 importorg.springframework.test.context.ContextConfiguration;5 importorg.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;6 importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner;7
8 //指定bean注入的配置文件
9 @ContextConfiguration(locations = { "classpath:application.xml"})10 //使用标准的JUnit @RunWith注释来告诉JUnit使用Spring TestRunner
11 @RunWith(SpringJUnit4ClassRunner.class)12 public class SpringTestCase extendsAbstractJUnit4SpringContextTests {13
14 }
1 packagecom.luo.service;2
3 importorg.junit.Test;4 importorg.springframework.beans.factory.annotation.Autowired;5 importorg.springframework.data.redis.core.RedisTemplate;6 importorg.springframework.data.redis.core.ValueOperations;7
8 importcom.luo.baseTest.SpringTestCase;9 importcom.luo.redis.model.User;10
11 public class RedisTestServiceTest extendsSpringTestCase {12
13 @Autowired14 private RedisTemplateredisTemplate;15 @Autowired16 privateUserService userService;17
18 @Test19 public void redisTest() throwsInterruptedException {20
21 User user = newUser();22 user.setUsername("zhangsan");23 user.setPassword("123456");24 user.setAge(10);25 user.setEmail("192554785@163.com");26 user.setId(10);27 System.out.println("=======addUser===================");28 userService.addUser(user);29 //System.out.println("=======第一次getUserByID============");30 //System.out.println(userService.getUserByID(11));31 //System.out.println("=======第二次getUserByID============");32 //System.out.println(userService.getUserByID(11));33 //System.out.println("===============================");34 //ValueOperations opsForValue = redisTemplate.opsForValue();35 //System.out.println("set前:"+opsForValue.get("user"));36 //opsForValue.set("user", user);37 //System.out.println("set后:"+opsForValue.get("user"));38 //redisTemplate.delete("user");39 //System.out.println("delete后:"+opsForValue.get("user"));
40 }41 }
测试结果:
set前:null
set后:10:zhangsan:123456:10:192554785@163.com
delete后:null
测试:getUserByID
=======第一次getUserByID============
@Cacheable注解方法被调用啦。。。。。
123:zhangsan:123456:10:192554785@163.com
=======第二次getUserByID============
123:zhangsan:123456:10:192554785@163.com
===============================
测试:addUser
1 @CachePut(value=”“,condition=”“,key=”“,unless=”“)2
3 public @interfaceCachePut {4 String[] value(); //缓存的名字,可以把数据写到多个缓存
5 String key() default ""; //缓存key,如果不指定将使用默认的KeyGenerator生成,后边介绍
6 String condition() default ""; //满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断
7 String unless() default ""; //用于否决缓存更新的,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了
8 }9
10
11 @Cacheable(value=”“,condition=”“,key=”“,unless=”“)12
13 public @interfaceCacheable{14 String[] value(); //缓存的名字,可以把数据写到多个缓存
15 String key() default ""; //缓存key,如果不指定将使用默认的KeyGenerator生成,后边介绍
16 String condition() default ""; //满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断
17 String unless() default ""; //用于否决缓存更新的,不像condition,该表达只在方法执行之后判断,此时可以拿到返回值result进行判断了
18 }19
20
21 @Cacheable(value=”“,condition=”“,key=”“,unless=”“)22
23 public @interfaceCacheEvict {24 String[] value(); //缓存的名字,可以把数据写到多个缓存
25 String key() default ""; //缓存key,如果不指定将使用默认的KeyGenerator生成,后边介绍
26 String condition() default ""; //满足缓存条件的数据才会放入缓存,condition在调用方法之前和之后都会判断
27 boolean allEntries() default false; //是否移除所有数据
28 boolean beforeInvocation() default false;//是调用方法之前移除/还是调用之后移除
29
30 @Caching(value=”“,condition=”“,key=”“,unless=”“)31
32 public @interfaceCaching {33
34 Cacheable[] cacheable() default {}; //从缓存获取多个,如果没有则执行方法体,获取值后加入缓存
35
36 CachePut[] put() default {}; //缓存多个
37
38 CacheEvict[] evict() default {}; //从缓存移除多个
39
40 }
例如:
1 @Caching(put ={2 @CachePut(value = "user", key = "'user_id_'+#user.id"),3 @CachePut(value = "user", key = "'user_username_'+#user.username"),4 @CachePut(value = "user", key = "'user_email_'+#user.email")5 }6
7 @Caching(cacheable ={8 @Cacheable(value = "user", key = "'user_id_'+#user.id"),9 @Cacheable(value = "user", key = "'user_username_'+#user.username"),10 @Cacheable(value = "user", key = "'user_email_'+#user.email")11 })12
13 @Caching(evict={14 @CacheEvict(value="",key="",condition="",allEntries=false,beforeInvocation=false),15 @CacheEvict(value="",key="",condition="",allEntries=false,beforeInvocation=false),16 @CacheEvict(value="",key="",condition="",allEntries=false,beforeInvocation=false)17 })
运行流程:
1、首先执行@CacheEvict(如果beforeInvocation=true且condition 通过),如果allEntries=true,则清空所有
2、接着收集@Cacheable(如果condition 通过,且key对应的数据不在缓存),放入cachePutRequests(也就是说如果cachePutRequests为空,则数据在缓存中)
3、如果cachePutRequests为空且没有@CachePut操作,那么将查找@Cacheable的缓存,否则result=缓存数据(也就是说只要当没有cache put请求时才会查找缓存)
4、如果没有找到缓存,那么调用实际的API,把结果放入result
5、如果有@CachePut操作(如果condition 通过),那么放入cachePutRequests
6、执行cachePutRequests,将数据写入缓存(unless为空或者unless解析结果为false);
7、执行@CacheEvict(如果beforeInvocation=false 且 condition 通过),如果allEntries=true,则清空所有
流程中需要注意的就是2/3/4步:如果有@CachePut操作,即使有@Cacheable也不会从缓存中读取;问题很明显,如果要混合多个注解使用,不能组合使用@CachePut和@Cacheable;官方说应该避免这样使用(解释是如果带条件的注解相互排除的场景);不过个人感觉还是不要考虑这个好,让用户来决定如何使用,否则一会介绍的场景不能满足。
CachePut与Cacheable区别:@CachePut:这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中。@Cacheable:当重复使用相同参数调用方法的时候,方法本身不会被调用执行,即方法本身被略过了,取而代之的是方法的结果直接从缓存中找到并返回了,如果从缓存中没有找到数据,则会执行方法,并且将返回值加入到缓存,当再次执行该方法获取时,会直接从缓存中拿,而不会执行方法体。
@CachePut和@Cacheable这两个标签可以结合使用,当需要根据请求改变值的时候,利用@CachePut将值改变并写入到缓存中,而@Cacheable标签除了第一次之外,一直是取的缓存的值。注意结合使用时需要注意两点:1、必须是同一个缓存实例。2、key值必须是相同的。
java redis 注解_Spring集成Redis使用注解相关推荐
- java集成redis集群_spring集成redis cluster详解
客户端采用最新的jedis 2.7 1.maven依赖: redis.clients jedis 2.7.3 2.增加spring 配置 classpath:connect-redis.propert ...
- java中spring的注解_spring中的各种注解解析
Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...
- 如果redis哨兵宕机了怎么办_Spring集成Redis做缓存,Redis宕机时Spring处理的问题
采用的是Spring自带的缓存管理,使用Redis做缓存,在Spring中配置如下 @Configuration @EnableCaching public class CachingConfig { ...
- enablefeignclients 注解_Spring Boot 中 @EnableXXX 注解的驱动逻辑
作者 | 温安适 来源 | https://juejin.im/post/5efdd689e51d4534af686ca9 点击赠书:聊聊「分布式架构」那些事儿 工作中经常用到,如下注解: @Enab ...
- redis笔记——springboot集成redis
Sprigboot整合 springboot整合数据操作一般会通过官方的一个项目springdata来进行整合,它可以操作很多市面上流行的数据库,并且为java程序提供一套完整的统一的api调用.在s ...
- Spring Boot集成Redis,这个坑把我害惨了!
最近项目中使用SpringBoot集成Redis,踩到了一个坑:从Redis中获取数据为null,但实际上Redis中是存在对应的数据的.是什么原因导致此坑的呢? 本文就带大家从SpringBoot集 ...
- 高并发秒杀——SpringBoot集成redis
shop--13.升级--Redis缓存技术 集成Redis 1.添加Jedis依赖 2.添加Fastjson依赖 1.安装redis http://www.runoob.com/redis/red ...
- 搞懂分布式技术14:Spring Boot使用注解集成Redis缓存
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a724888/article/details/80785403 为了提高性能,减少数据库的压力,使用 ...
- Spring Boot集成Redis缓存之注解方式
首先还是加入依赖Jar pom.xml中加入依赖 <!-- 加载spring boot redis 包 --><dependency><groupId>org.sp ...
最新文章
- CoreData的简单使用
- python真的那么火吗-Python语言为什么这么火?
- wireshark的使用
- Erlang的边界检查(3)
- Powerful array CodeForces - 86D (莫队算法)
- Jimu : .Net Core 分布式微服务框架介绍
- 大数据分析的特点有哪些
- 集合字典序(优先队列)
- 机器人总动员中的小草_机器人总动员观后感(精选4篇)
- 使用Bartend提取K3领料数据以实现发料包装标识批量自动打印
- Exosip源码学习2
- 按摩器具抽查三成不合格 选购需注意哪些?
- 丢花娟(约瑟夫环问题)
- loss 加权_为每个类别/实例编写自定义损失加权,对,的,loss
- 有源与无源晶振的区别
- loaders之val-loader
- 4k分辨率是多少(真4k与假4k区别)
- 将图片转化为数据储存
- const int *,const int * const和int const *之间的区别
- mysql的master slave_Mysql 数据库的同步(master slave) 详解