源码:https://github.com/614756773/springredis
需要的jar包:
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.4.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
目录结构:
User.java:
package com.huoguo.bean;
import java.io.Serializable;
public class User implements Serializable{
private String name;
private int age;
private long creatTime;
public User(){}
public User(String name, int age, long creatTime) {
this.name = name;
this.age = age;
this.creatTime = creatTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public long getCreatTime() {
return creatTime;
}
public void setCreatTime(long creatTime) {
this.creatTime = creatTime;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", creatTime=" + creatTime +
'}';
}
}
该类必须实现Serializable接口,不然无法从redis缓存中将对象读取出来
RedisCacheConfig.java:
package com.huoguo.redis;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import java.lang.reflect.Method;
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
private volatile JedisConnectionFactory mJedisConnectionFactory;
private volatile RedisTemplate<String, String> mRedisTemplate;
private volatile RedisCacheManager mRedisCacheManager;
public RedisCacheConfig() {
super();
}
public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) {
super();
this.mJedisConnectionFactory = mJedisConnectionFactory;
this.mRedisTemplate = mRedisTemplate;
this.mRedisCacheManager = mRedisCacheManager;
}
public JedisConnectionFactory redisConnectionFactory() {
return mJedisConnectionFactory;
}
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
return mRedisTemplate;
}
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
return mRedisCacheManager;
}
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}
Myserver.java:
package com.huoguo.server;
import com.huoguo.bean.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class Myserver {
@Cacheable(value = "cacheA")
public User getUserByAgeAndName(String name,int age){
return new User(name,age,System.currentTimeMillis());
}
@Cacheable(value = "cacheB")
public User getUserByName(String name){
User u=new User();
u.setName(name);
u.setCreatTime(System.currentTimeMillis());
return u;
}
@CacheEvict(value = {"cacheA","cacheB"},allEntries = true)
public void clearCache(){
System.out.println("clear over");
}
}
@Cacheable(value = "cacheA")注解的作用:
①当调用注解下方的方法时会在redis缓存中存入一个缓存数据(类型是zset),其key为 cacheA~keys,value为此方法返回的User对象
②当下一次使用此方法,且传入的name,age参数是同之前的一样时就不会执行方法体,而是直接从redis缓存中得到数据。
此处我特意为User类添加了一个creatTime字段,用于测试的时候判断到底是不是从缓存中拿到了原来的数据
@CacheEvict(value = {"cacheA","cacheB"},allEntries = true):
当调用该注解下方的方法时,删除redis缓存中的cacheA和cacheB缓存,allEntries = true表示删除所有,因为cacheA和cacheB中可以不止存一条数据
redis.properties:
# Redis settings
redis.host=127.0.0.1
redis.port=6379
#redis.pass=password
redis.dbIndex=0
redis.expiration=3000
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
spring.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<description>redis 相关类 Spring 托管</description>
<context:component-scan base-package="com.huoguo.server"/>
<!--载入 redis 配置文件-->
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>
<!-- 配置 JedisPoolConfig 实例 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}"/>
<property name="maxTotal" value="${redis.maxActive}"/>
<property name="maxWaitMillis" value="${redis.maxWait}"/>
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<!-- 配置JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value=""/>
<property name="database" value="${redis.dbIndex}"/>
<property name="poolConfig" ref="poolConfig"/>
</bean>
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
</bean>
<!-- 配置RedisCacheManager -->
<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate"/>
<property name="defaultExpiration" value="${redis.expiration}"/>
</bean>
<!-- 配置RedisCacheConfig -->
<bean id="redisCacheConfig" class="com.huoguo.redis.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory"/>
<constructor-arg ref="redisTemplate"/>
<constructor-arg ref="redisCacheManager"/>
</bean>
</beans>
测试方法:
import com.huoguo.bean.User;
import com.huoguo.server.Myserver;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
Myserver myserver= (Myserver) ctx.getBean("myserver");
User u =myserver.getUserByName("大白");
Thread.sleep(2000);
User u2=myserver.getUserByName("大白");
System.out.println(u);
System.out.println(u2);
System.out.println(u==u2);
}
}
我们可以预测一下结果,如果缓存起作用了的话u和u2对象的创建时间应该是一样的而不会相差2000毫秒,因为u2其实是从redis缓存中取到的
结果:
的确,两个对象的数据完全一样了,但是。。。他们却不是同一个引用,这个我不是很清楚,只能推测u2其实是u缓存的复制