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

===============================

测试:addUsera3a9b72705a797be18ed9866242167f3.png

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值必须是相同的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值