一、简介
在文章spring缓存(一)--内存缓存中,我们介绍了spring内存缓存的使用,
在本文我们介绍将redis缓存集成到spring缓存管理中。
二、开发流程
1、添加maven依赖
org.springframework spring-core 4.3.6.RELEASE org.springframework spring-beans 4.3.6.RELEASE org.springframework spring-context 4.3.6.RELEASE org.springframework spring-context-support 4.3.6.RELEASE org.springframework spring-aop 4.3.6.RELEASE org.springframework spring-asm 3.1.4.RELEASE org.springframework spring-aspects 4.3.6.RELEASE org.springframework spring-expression 4.3.6.RELEASE cglib cglib 3.2.4 redis.clients jedis 2.9.0 org.springframework.data spring-data-redis 1.8.0.RELEASE com.fasterxml.jackson.core jackson-core 2.8.6 com.fasterxml.jackson.core jackson-databind 2.8.6 com.fasterxml.jackson.core jackson-annotations 2.8.6 org.codehaus.jackson jackson-mapper-asl 1.9.13 org.codehaus.jackson jackson-mapper-lgpl 1.9.13 org.apache.commons commons-pool2 2.4.2
2、在spring中添加redis配置(详情请查看文章spring与redis整合(二)--采用spring-data-redis方式),配置如下:
xml version="1.0" encoding="UTF-8"?>3、实现org.springframework.cache.Cache接口,定义redis缓存实现类,如下: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: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.xsd "> <context:component-scan base-package="com.dragon.study" /> id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" p:maxTotal="6000" p:maxIdle="300" p:minIdle="100" p:maxWaitMillis="1500" /> id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:hostName="127.0.0.1" p:port="6379" p:database="0" p:poolConfig-ref="jedisPoolConfig" /> id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connectionFactory-ref="jedisConnectionFactory" p:keySerializer-ref="stringRedisSerializer" p:valueSerializer-ref="jdkSerializationRedisSerializer" p:hashKeySerializer-ref="stringRedisSerializer" p:hashValueSerializer-ref="jdkSerializationRedisSerializer" /> id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connectionFactory-ref="jedisConnectionFactory" /> id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
public class RedisCache implements Cache { @Resource private RedisTemplate redisTemplate; @Resource(name="redisTemplate") private ValueOperations valOps; private String name; //缓存名称 private long timeout=1*1000; //缓存时间,单位毫秒 ,默认一秒 @Override public String getName() { return this.name; } public void setName(String name){ this.name = name; } @Override public Object getNativeCache() { //缓存的实现 return this.redisTemplate; } @Override public ValueWrapper get(Object o) { return toWrapper(valOps.get(o)); } @Override public <T> T get(Object o, Class<T> aClass) { return (T) valOps.get(o); } @Override public <T> T get(Object o, Callable<T> callable) { return (T) valOps.get(o); } @Override public void put(Object o, Object o1) { valOps.set(o,o1,timeout, TimeUnit.MILLISECONDS); } @Override public ValueWrapper putIfAbsent(Object o, Object o1) { valOps.setIfAbsent(o,o1); return null; } @Override public void evict(Object o) { valOps.getOperations().delete(o); } @Override public void clear() { redisTemplate.execute(new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { connection.flushDb(); return null; } }); } public long getTimeout() { return timeout; } public void setTimeout(long timeout) { this.timeout = timeout; } private ValueWrapper toWrapper(Object value) { return (value != null ? new SimpleValueWrapper(value) : null); } }4、spring中配置redis缓存实现(方式如文章spring缓存(一)--内存缓存)
xml version="1.0" encoding="UTF-8"?>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:cache="http://www.springframework.org/schema/cache" 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.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd "> <context:component-scan base-package="com.dragon.study" /> <cache:annotation-driven /> id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> name="caches"> class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" /> class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="mycache" /> class="com.dragon.study.cache.RedisCache" p:name="redisCache" p:timeout="60000" />
5、将redis配置与cache配置合在一起的spring配置文件
xml version="1.0" encoding="UTF-8"?>6、使用(方式如文章spring缓存(一)--内存缓存)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:aop="http://www.springframework.org/schema/aop" 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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <context:component-scan base-package="com.dragon.study" /> <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true" /> resource="spring-redis.xml" /> resource="spring-cache.xml" />
@Service("studentRedisCache") public class StudentRedisCacheImpl implements StudentService { @Cacheable(value = "redisCache",key="'id_'+#id",condition = "#id<3") public Student getStudent(Integer id) { Student stu = new Student(); stu.setId(id); stu.setName("apple"); return stu; } @CachePut(value = "redisCache",key="'id_'+#stu.getId()") public Student updateStudent(Student stu){ System.out.println("update stu"); return stu; } @CacheEvict(value = "redisCache",key="'id_'+#id") public void deleteStudent(Integer id){ System.out.println("delete student "+id); } public void myDelete(Integer id){ try { StudentService ss = (StudentService) AopContext.currentProxy(); ss.deleteStudent(id); return ; }catch (Exception e){ e.printStackTrace(); } this.deleteStudent(id); } @CacheEvict(value = "redisCache",allEntries = true) public void deleteAllStudent(){ System.out.println("delete all student "); } }7、测试
public class SpringRedisCacheMain { public static void main(String[] args) { ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring-config.xml"); StudentService studentService = (StudentService) ac.getBean("studentRedisCache"); Integer id =1; Student stu = studentService.getStudent(id); //新建缓存 stu = studentService.getStudent(id); //从缓存中取 studentService.myDelete(id); stu = studentService.getStudent(id); //从缓存中取 stu.setName("banana"); //重新设置值 studentService.updateStudent(stu); //更新缓存 stu = studentService.getStudent(id); //从缓存中取出新值 stu = new Student(); //新实例 stu.setId(0); studentService.updateStudent(stu); //用新建的实例进行更新,会新建缓存 stu = studentService.getStudent(0); //从缓存中取 studentService.deleteStudent(id); // 删除缓存 stu = studentService.getStudent(id); //再次新建缓存 id=2; stu = studentService.getStudent(id); //新建缓存 studentService.deleteAllStudent(); //删除所有缓存 id=1; stu = studentService.getStudent(id); //因所有缓存被前一步清除,会新建缓存 id=5; stu = studentService.getStudent(id); //不会新建缓存 因为设置了缓存条件必须小于3 stu = studentService.getStudent(id); //因没有缓存,不会从缓存中取 Assert.notNull(stu); } }