使用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使用注解相关推荐

  1. java集成redis集群_spring集成redis cluster详解

    客户端采用最新的jedis 2.7 1.maven依赖: redis.clients jedis 2.7.3 2.增加spring 配置 classpath:connect-redis.propert ...

  2. java中spring的注解_spring中的各种注解解析

    Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...

  3. 如果redis哨兵宕机了怎么办_Spring集成Redis做缓存,Redis宕机时Spring处理的问题

    采用的是Spring自带的缓存管理,使用Redis做缓存,在Spring中配置如下 @Configuration @EnableCaching public class CachingConfig { ...

  4. enablefeignclients 注解_Spring Boot 中 @EnableXXX 注解的驱动逻辑

    作者 | 温安适 来源 | https://juejin.im/post/5efdd689e51d4534af686ca9 点击赠书:聊聊「分布式架构」那些事儿 工作中经常用到,如下注解: @Enab ...

  5. redis笔记——springboot集成redis

    Sprigboot整合 springboot整合数据操作一般会通过官方的一个项目springdata来进行整合,它可以操作很多市面上流行的数据库,并且为java程序提供一套完整的统一的api调用.在s ...

  6. Spring Boot集成Redis,这个坑把我害惨了!

    最近项目中使用SpringBoot集成Redis,踩到了一个坑:从Redis中获取数据为null,但实际上Redis中是存在对应的数据的.是什么原因导致此坑的呢? 本文就带大家从SpringBoot集 ...

  7. 高并发秒杀——SpringBoot集成redis

    shop--13.升级--Redis缓存技术 集成Redis 1.添加Jedis依赖 2.添加Fastjson依赖 1.安装redis  http://www.runoob.com/redis/red ...

  8. 搞懂分布式技术14:Spring Boot使用注解集成Redis缓存

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a724888/article/details/80785403 为了提高性能,减少数据库的压力,使用 ...

  9. Spring Boot集成Redis缓存之注解方式

    首先还是加入依赖Jar pom.xml中加入依赖 <!-- 加载spring boot redis 包 --><dependency><groupId>org.sp ...

最新文章

  1. CoreData的简单使用
  2. python真的那么火吗-Python语言为什么这么火?
  3. wireshark的使用
  4. Erlang的边界检查(3)
  5. Powerful array CodeForces - 86D (莫队算法)
  6. Jimu : .Net Core 分布式微服务框架介绍
  7. 大数据分析的特点有哪些
  8. 集合字典序(优先队列)
  9. 机器人总动员中的小草_机器人总动员观后感(精选4篇)
  10. 使用Bartend提取K3领料数据以实现发料包装标识批量自动打印
  11. Exosip源码学习2
  12. 按摩器具抽查三成不合格 选购需注意哪些?
  13. 丢花娟(约瑟夫环问题)
  14. loss 加权_为每个类别/实例编写自定义损失加权,对,的,loss
  15. 有源与无源晶振的区别
  16. loaders之val-loader
  17. 4k分辨率是多少(真4k与假4k区别)
  18. 将图片转化为数据储存
  19. const int *,const int * const和int const *之间的区别
  20. mysql的master slave_Mysql 数据库的同步(master slave) 详解

热门文章

  1. 集线器、交换机、网桥和路由器如何隔离广播域和冲突域
  2. 【 HDU 1166】 敌兵布阵 树状数组从0到1
  3. 蒙特卡罗模拟概述(Monte Carlo Simulation)
  4. 自然场景OCR检测(YOLOv3+CRNN)
  5. Solr索引之增删改查
  6. 关于记事本如何快速删除
  7. Linux Shell程序设计(2)
  8. Mac下编程相关软件安装
  9. 关于Android Studio 中Android SDK的 SDK Tools 没有CMake下载项问题
  10. 深聊全链路压测之:第二十三讲 | 如何改造性能监控。