项目地址:
https://github.com/CarrowZhu/springredis
项目简介:
基于spring-data-redis的注解实现redis缓存操作
requirement
JDK6
Spring4
原理&实现
1)AOP
2)实现参考自Spring的Cache注解
区别:
1)支持TTL
2)支持Hash
配置说明
XML配置文件
xsi:schemaLocation="http://www.siyuan.com/schema/springredis
http://www.siyuan.com/schema/springredis/springredis.xsd"
<springRedis:annotation-driven />
属性说明
redisTemplate:Advice中将使用的redisTemplate,默认为"redisTemplate"
order:Advice的执行顺序,默认优先级最高(Ordered.HIGHEST_PRECEDENCE)
exceptionHandler:beanId,操作异常处理器,必须实现接口com.siyuan.springredis.interceptor.SpringRedisExceptionHandler,默认为com.siyuan.springredis.interceptor.LoggerExceptionHandler
注解
1)@SpringRedisConfig:Class级别配置
属性说明
value:等同于redisTemplate
redisTemplate:(String)Advice中将使用的redisTemplate
2)@SpringRedisValueCache:方法级别,操作的数据类型为String
对应操作流程:读cache,hit返回,miss -> 获取数据 -> cache
属性说明
value:等同于key
redisTemplate:(String)Advice中将使用的redisTemplate
condition:(String)支持SpringEL,缓存操作条件
timeout:(long)TTL,<=0表示永不过期,默认为0
timeUnit:(TimeUnit)TTL单位,默认为TimeUnit.MILLISECONDS
key:(String)支持SpringEL,缓存对应的key值,必须提供
refreshTTL:(boolean)缓存命中时是否刷新TTL,默认为false
3)@SpringRedisValueEvict :方法级别,操作的数据类型为String
对应的流程:清除缓存
属性说明
value:等同于key
redisTemplate:(String)Advice中将使用的redisTemplate
condition:(String)支持SpringEL,缓存操作条件
key:(String)支持SpringEL,缓存对应的key值,必须提供
4)@SpringRedisHashCache:方法级别,操作的数据类型为Hash
对应操作流程:与 @SpringRedisValueCache 类似
属性说明
value:等同于key
redisTemplate:(String)Advice中将使用的redisTemplate
condition:(String)支持SpringEL,缓存操作条件
timeout:(long)TTL,<=0表示永不过期,默认为0
timeUnit:(TimeUnit)TTL单位,默认为TimeUnit.MILLISECONDS
key:(String)支持SpringEL,缓存对应的key值,必须提供
refreshTTL:(boolean)缓存命中时是否刷新TTL,默认为false
hashKey:(String)支持SpringEL,缓存对应的hashKey值,必须提供
5)@SpringRedisHashEvict :方法级别,操作的数据类型为Hash
对应的流程:与 @SpringRedisValueEvict 类似
属性说明
value:等同于key
redisTemplate:(String)Advice中将使用的redisTemplate
condition:(String)支持SpringEL,缓存操作条件
key:(String)支持SpringEL,缓存对应的key值,必须提供
hashKey:(String)支持SpringEL,缓存对应的hashKey值,必须提供
SpringEL
Name > Location > Example
methodName > root object > #root.methodName
method > root object > #root.method.name
target > root object > #root.target
targetClass > root object > #root.targetClass
args > root object > #root.args[0]
argument name > evaluation context > #name (编译时必须保留方法名信息)
result > evaluation context > #result
示例
1)ApplicationContext-SpringRedis.xml
<?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:springRedis="http://www.siyuan.com/schema/springredis" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.siyuan.com/schema/springredis http://www.siyuan.com/schema/springredis/springredis.xsd"> <springRedis:annotation-driven /> <context:component-scan base-package="com.siyuan.springredis" /> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" /> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory" p:key-serializer-ref="stringRedisSerializer"> <property name="defaultSerializer"> <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /> </property> </bean> <bean id="studentRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory" p:key-serializer-ref="stringRedisSerializer" p:hash-key-serializer-ref="stringRedisSerializer"> <property name="defaultSerializer"> <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer"> <constructor-arg index="0" value="#{T(com.siyuan.springredis.Student)}" /> </bean> </property> </bean> </beans>
2)Student.java
package com.siyuan.springredis; public class Student { private Long id; private String name; public Student() { } public Student(Long id, String name) { this.id = id; this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + "]"; } }
3)StudentDAO.java
package com.siyuan.springredis; public interface StudentDAO { Student getById(long id); void updateStudent(Student student); }
4)StudentService.java
package com.siyuan.springredis; import java.util.concurrent.TimeUnit; import org.springframework.stereotype.Service; import com.siyuan.springredis.annotation.SpringRedisConfig; import com.siyuan.springredis.annotation.SpringRedisHashCache; import com.siyuan.springredis.annotation.SpringRedisHashEvict; import com.siyuan.springredis.annotation.SpringRedisValueCache; import com.siyuan.springredis.annotation.SpringRedisValueEvict; @Service("studentService") @SpringRedisConfig("studentRedisTemplate") public class StudentService { private StudentDAO studentDAO; @SpringRedisValueCache(key = "'student:' + #id", condition = "#id > 100", timeout = 60, timeUnit = TimeUnit.MINUTES, refreshTTL = true) public Student getById(long id) { return studentDAO.getById(id); } @SpringRedisValueEvict(key = "'student:' + #student.id", condition = "#student.id > 100") public void updateStudent(Student student) { studentDAO.updateStudent(student); } @SpringRedisHashCache(key = "'students'", hashKey = "#id.toString()", condition = "#id > 100", timeout = 60, timeUnit = TimeUnit.MINUTES, refreshTTL = true) public Student getById2(long id) { return studentDAO.getById(id); } @SpringRedisHashEvict(key = "'students'", hashKey = "#student.id.toString()", condition = "#student.id > 100") public void updateStudent2(Student student) { studentDAO.updateStudent(student); } public StudentDAO getStudentDAO() { return studentDAO; } public void setStudentDAO(StudentDAO studentDAO) { this.studentDAO = studentDAO; } }
5)StudentServiceTest.java
package com.siyuan.springredis.test; import org.junit.After; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import static org.mockito.Mockito.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.siyuan.springredis.Student; import com.siyuan.springredis.StudentDAO; import com.siyuan.springredis.StudentService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "/ApplicationContext-SpringRedis.xml") public class StudentServiceTest { @Autowired @Qualifier("studentRedisTemplate") private RedisTemplate<String, Student> redisTemplate; @Autowired private StudentService service; private StudentDAO studentDAO; private StudentDAO mock; @Before public void setUp() { redisTemplate.delete("student:123"); redisTemplate.delete("student:100"); redisTemplate.delete("students"); studentDAO = service.getStudentDAO(); mock = mock(StudentDAO.class); service.setStudentDAO(mock); } @Test public void testGetById() { when(mock.getById(123L)).thenReturn(new Student(123L, "name:123")); // no cache Student stu = service.getById(123L); assertArrayEquals(new Object[] { new Student(123L, "name:123") }, new Object[] { stu }); // cache stu = service.getById(123L); assertArrayEquals(new Object[] { new Student(123L, "name:123") }, new Object[] { stu }); verify(mock, times(1)).getById(123L); when(mock.getById(100L)).thenReturn(new Student(100L, "name:100")); // no cache stu = service.getById(100L); assertArrayEquals(new Object[] { new Student(100L, "name:100") }, new Object[] { stu }); // no cache stu = service.getById(100L); assertArrayEquals(new Object[] { new Student(100L, "name:100") }, new Object[] { stu }); verify(mock, times(2)).getById(100L); } @Test public void testUpdateStudent() { // evict Student stu = new Student(123L, "name:123"); redisTemplate.opsForValue().set("student:123", stu); service.updateStudent(stu); assertNull(redisTemplate.opsForValue().get("student:123")); // do not evict stu = new Student(100L, "name:100"); redisTemplate.opsForValue().set("student:100", stu); service.updateStudent(stu); assertNotNull(redisTemplate.opsForValue().get("student:100")); } @Test public void testGetById2() { when(mock.getById(123L)).thenReturn(new Student(123L, "name:123")); // no cache Student stu = service.getById2(123L); assertArrayEquals(new Object[] { new Student(123L, "name:123") }, new Object[] { stu }); // cache stu = service.getById2(123L); assertArrayEquals(new Object[] { new Student(123L, "name:123") }, new Object[] { stu }); verify(mock, times(1)).getById(123L); when(mock.getById(100L)).thenReturn(new Student(100L, "name:100")); // no cache stu = service.getById2(100L); assertArrayEquals(new Object[] { new Student(100L, "name:100") }, new Object[] { stu }); // no cache stu = service.getById2(100L); assertArrayEquals(new Object[] { new Student(100L, "name:100") }, new Object[] { stu }); verify(mock, times(2)).getById(100L); } @Test public void testUpdateStudent2() { // evict Student stu = new Student(123L, "name:123"); redisTemplate.opsForHash().put("students", "123", stu); service.updateStudent2(stu); assertNull(redisTemplate.opsForHash().get("students", "123")); // do not evict stu = new Student(100L, "name:100"); redisTemplate.opsForHash().put("students", "100", stu); service.updateStudent2(stu); assertNotNull(redisTemplate.opsForHash().get("students", "100")); } @After public void clear() { service.setStudentDAO(studentDAO); } }
相关推荐
分布式开发项目spring+SpringMVc+mybatis+dubbo+redis+netty
基于netty, spring boot, redis等开源项目开发来的物联网框架, 支持udp, tcp底层协议和http, mqtt, modbus等上层协议. 支持对设备同步和异步的调用操作. 主要向开发人员开放了一套统一、简洁的用于操作设备的Api接口...
iot-ucy是使用java语言且基于netty, spring boot, redis等开源项目开发来的物联网网络中间件, 支持udp, tcp, 串口(com)通讯(window、linux、mac)等底层协议和http, mqtt, websocket(默认实现和自定义协议头实现), ...
SpringBlog 是开源博客系统,主要用的到的技术有: Spring MVC Spring Data JPA Hibernate MySQL Spring Data Redis 用于缓存文章 Jade 作为视图模板,我极度不喜欢写 HTML 标签 Bootstrap 没有它我就...
免费开源的小额贷款管理系统,基于主流的spring,easyui等开源技术框架,通用 的贷款业务流程,更易于二次开发和维护,为不同业务的贷款软件提供产品基础
springboot整合redis.算是比较全面的一种整合方式了. springboot整合redis.算是比较全面的一种整合方式了.
在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。 Spring Data Redis中提供了一个高度封装的类:**RedisTemplate**,针对 Jedis 客户端中大量api进行了归类封装,将同一类型操作封装为operation接口...
计算机课程设计基于SSM的JAVA商城系统-毕业设计课程设计项目-redis的轻量级、前后端分离 一个基于spring boot、spring oauth2.0、mybatis、redis的轻量级、前后端分离、防范xss攻击、 一个完整、易于维护的开源的...
本项目JDK8x64+SpringBoot+MyBatis+Redis+Druid+Beetl+Shrio的框架组合,自研工作流引擎,支持可视化表单设计与流程设计。支技分布式部署。功能完善能够满足中大型企业办公需要。 本项目自2020-08-17日起,为全面...
3、该项目采用了struts2 hibernate spring和 spring data jpa 开源框架完成,并融入了cxf开源webservice框架的应用,而这些技术都是当下流行的技术。 4、在缓存方面运用了互联网的流行技术redis实现缓存存贮,...
Spring Data Redis, 是 Spring Data 家族的子项目。它提供了 Spring 应用对 Redis 的简单配置和访问。低级和高级的抽象用于存储,使用户无需考虑考虑基础。 标签:Spring redis
该项目主要技术架构包括:spring+springMVC+Mybatis+MYSQL+Redis+Maven,适合初学者,简单易懂。
简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!...
百度云盘分享 简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、中级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对...
后端采用Spring Boot、Spring Security、Redis & Jwt、Mybatis Plus、WxJava。 小程序端采用原生框架+Color UI。 权限认证使用Jwt,支持多终端认证系统。 支持加载动态权限菜单,多方式轻松权限控制。 高效率开发,...
iot物联网框架基于netty, spring boot, redis等开源项目开发来的物联网框架, 支持udp, tcp底层协议和http, mqtt, modbus等上层协议. 支持对设备同步和异步的调用操作. 主要向开发人员开放了一套统一、简洁的用于操作...
下载分设置的比较高,不过绝对的...为了在接下来的项目中能够方便的控制和使用 redis,所以也粗略的模仿了下membercache的aop代码,写了一份spring-redis-aop。当然方法有很多种,也许你有更好的 使用方法当然更好哈。
面试刷题开源系统,学习搭建SpringBoot项目,SpringCloud项目。采用流行的技术,如SpringBoot、Mybatis、Redis、MySql、Elasticsearch,采用Docker容器化部署