`
风过无声
  • 浏览: 92438 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

开源项目springredis

 
阅读更多

项目地址:

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整合redis项目

    Redis是一款开源的、高性能的键值对数据库,而Spring是Java领域广泛使用的框架,提供了一整套的企业级应用开发工具。将Spring与Redis结合,可以方便地在应用程序中利用Redis的强大功能。 一、Spring Data Redis概述...

    spring redis 分布式缓存整合详细的注释说明

    Spring Redis是Spring Data项目的一部分,它提供了对Redis数据存储的高级抽象,支持多种操作模式,如Jedis和Lettuce客户端。通过Spring Redis,开发者可以轻松地将缓存功能引入到Spring应用程序中。 二、Redis基础...

    spring redis

    Spring Data Redis项目简化了在Spring应用中使用Redis的过程。首先,你需要在项目中添加Spring Data Redis的依赖,通常在Maven或Gradle的配置文件中进行: ```xml &lt;!-- Maven 示例 --&gt; &lt;groupId&gt;org.spring...

    项目整合redis实战

    8. **Spring Boot样例项目分析**:`spring-boot-sample-Redis`可能包含了一个简单的Spring Boot应用,演示了如何配置Redis,以及如何使用RedisTemplate进行数据操作。通过阅读源代码,你可以深入理解如何在实际项目...

    SpringDataRedis的jar包.rar

    Spring Data Redis是一个强大的Java库,它是Spring Data项目的一部分,旨在简化与Redis内存数据存储的集成。Redis是一个开源的、高性能的键值数据存储系统,常用于数据库、缓存和消息中间件。Spring Data Redis提供...

    spring--redis所需要的所有jar

    在Java开发领域,Spring框架与Redis的集成是常见的数据存储和缓存解决方案。Spring提供了对多种数据源的支持,...通过上述步骤,你已经具备了使用Spring与Redis集成的基础,可以根据项目需求进行更深入的定制和优化。

    分布式开发项目spring+SpringMVc+mybatis+dubbo+redis+netty.rar

    本项目结合了Spring、SpringMVC、MyBatis、Dubbo、Redis和Netty等技术,构建了一个完整的分布式服务系统。 1. **Spring框架**:Spring是Java企业级应用的核心框架,提供了依赖注入(DI)和面向切面编程(AOP)等...

    spring+redis整合

    这个"spring+redis整合"项目展示了如何利用Spring框架和Redis数据库来实现一个高效的、高可用的登录系统,其中会话(Session)由Redis进行管理,同时支持通过Nginx进行负载均衡。以下是关于这一主题的详细知识讲解。...

    spring+redis整合用例

    1. **添加依赖**:在项目中引入Spring Data Redis和Redis客户端库(如Jedis或Lettuce)的依赖。在Maven项目中,可以在pom.xml文件中添加对应的dependency。 2. **配置Redis**:在Spring的配置文件(如...

    spring+redis整合demo

    - "SpringRedis"这个文件夹可能包含了一个完整的Spring Boot项目,其中包括了`pom.xml`配置文件、`application.properties`或`application.yml`配置文件,以及相关的Java源代码。 - 源代码中可能会有Redis配置类、...

    java开源web项目

    "liugh-openResources"这个文件名可能指的是一个开源项目或资源库,其中包含了与Java Web相关的各种组件、文档、示例代码和配置文件。这个压缩包可能包含了一个完整的Web项目实例,或者是一些用于教学或参考的开源...

    iot是基于netty, spring boot, redis,mqtt等开源项目实现的物联网框架, 支持tcp, udp

    基于netty, spring boot, redis等开源项目开发来的物联网框架, 支持udp, tcp底层协议和http, mqtt, modbus等上层协议. 支持对设备同步和异步的调用操作. 主要向开发人员开放了一套统一、简洁的用于操作设备的Api接口...

    spring+redis的Demo

    2. **添加依赖**:在Spring项目中,需要在Maven或Gradle的配置文件中引入Redis的相关依赖。如果是Maven,可以在`pom.xml`中添加以下依赖: ```xml &lt;groupId&gt;org.springframework.boot &lt;artifactId&gt;spring-boot-...

    spring-redis-mysql整合

    在IT行业中,Spring框架是Java领域最常用的轻量级开源框架之一,而Redis则是一种高性能的内存数据存储系统,常用于缓存、消息队列等场景。MySQL则是世界上最流行的开源关系型数据库。将Spring、Redis和MySQL整合在...

    spring整合redis小demo

    首先,我们需要在项目中引入Spring对Redis支持的相关依赖。在Maven项目中,可以在pom.xml文件中添加如下依赖: ```xml &lt;groupId&gt;org.springframework.boot &lt;artifactId&gt;spring-boot-starter-data-redis ``` 接...

    spring data redis 小例子

    首先,Spring Data Redis是Spring Data项目的一部分,该项目致力于简化各种数据存储的访问,包括关系型数据库、NoSQL存储以及缓存系统如Redis。通过Spring Data Redis,你可以使用Java或Groovy API来方便地执行Redis...

    dubbo spring mybatis redis

    【标题】"dubbo spring mybatis redis" 涵盖了四个关键的开源技术,它们在企业级应用开发中扮演着重要角色。Dubbo 是一个高性能、轻量级的 Java RPC 框架,用于构建分布式服务。Spring 是一个广泛使用的 Java 应用...

    Spring+Struts2+hibernate+Redis整合

    4. **Redis**:Redis是一个开源的内存数据结构存储系统,支持多种数据类型如字符串、哈希、列表、集合和有序集合。在Java应用中,我们可以使用Jedis或者Lettuce等客户端库与Redis通信。在SSH框架中,Redis常用于缓存...

    Spring-session2整合spring5+redis

    Spring Session是一个开源项目,旨在提供一个统一的方式来管理和共享应用程序会话数据,支持多种存储后端,包括Redis。Redis则是一个高性能的键值数据库,常被用作缓存和会话存储。 描述中的“spring5+hibernate5+...

    spring与Redis的入门Demo

    2. **配置 Redis**:在 Spring Boot 项目中,可以在 `application.properties` 或 `application.yml` 文件中配置 Redis 连接信息,如主机名、端口、密码等: ```properties spring.redis.host=localhost spring....

Global site tag (gtag.js) - Google Analytics