spring cache整合redis

        在项目中,我们经常需要将一些常用的数据使用缓存起来,避免频繁的查询数据库造成效率低下。spring 为我们提供了一套基于注解的缓存实现,方便我们实际的开发。我们可以扩展spring的cache接口以达到使用redis来做缓存的效果。

 

步骤:

1.编写一个类用于实现   org.springframework.cache.Cache  这个接口

2.编写一个类实现  org.springframework.cache.CacheManager 这个接口或继承 org.springframework.cache.support.AbstractCacheManager这个类

3.在配置文件中进行配置。

 

代码:

1.使用redis实现spring的cache接口 -- 数据以hash的方式存入到redis中

 

package com.huan.redis.springcache;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * 自定义redis缓存
 * 
 * @描述
 * @作者 huan
 * @时间 2016年6月26日 - 下午2:14:26
 */
public class RedisCache implements Cache {

	private JedisPool jedisPool;
	/** 缓存的过期时间,单位是秒 */
	private int timeouts;

	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}

	public int getTimeouts() {
		return timeouts;
	}

	public void setTimeouts(int timeouts) {
		this.timeouts = timeouts;
	}

	private String name;

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public Object getNativeCache() {
		return jedisPool;
	}

	@Override
	public ValueWrapper get(Object key) {
		ValueWrapper result = null;
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			String value = jedis.hget(getName(), (String) key);
			if (value != null) {
				result = new SimpleValueWrapper(value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != jedis) {
				jedis.close();
			}
		}
		return result;
	}

	@Override
	public void put(Object key, Object value) {
		String cacheKey = (String) key;
		String cacheValue = (String) value;
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.hset(getName(), cacheKey, cacheValue);
			jedis.expire(getName(), getTimeouts());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != jedis) {
				jedis.close();
			}
		}
	}

	@Override
	public void evict(Object key) {
		if (null != key) {
			Jedis jedis = null;
			try {
				jedis = jedisPool.getResource();
				jedis.hdel(getName(), (String) key);
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (null != jedis) {
					jedis.close();
				}
			}
		}
	}

	@Override
	public void clear() {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.hdel(getName());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != jedis) {
				jedis.close();
			}
		}
	}
}

 2.实现自己的缓存管理器

 

 

package com.huan.redis.springcache;

import java.util.Collection;

import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractCacheManager;

/**
 * 继承spring的抽象缓存管理器,用于实现我们自己的缓存管理
 * @描述
 * @作者 huan
 * @时间 2016年6月26日 - 下午2:17:15
 */
public class RedisCacheManager extends AbstractCacheManager{

	private Collection<? extends RedisCache> caches;

	public void setCaches(Collection<? extends RedisCache> caches) {
		this.caches = caches;
	}

	@Override
	protected Collection<? extends Cache> loadCaches() {
		return this.caches;
	}

}

 3.配置文件中进行配置

 

 

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd
		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-3.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
	<context:annotation-config />
	<context:component-scan base-package="com.huan.redis" />
	<cache:annotation-driven cache-manager="cacheManager"/>
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="testWhileIdle" value="true" />
		<property name="minEvictableIdleTimeMillis" value="60000" />
		<property name="timeBetweenEvictionRunsMillis" value="30000" />
		<property name="numTestsPerEvictionRun" value="-1" />
		<property name="maxTotal" value="8" />
		<property name="maxIdle" value="8" />
		<property name="minIdle" value="0" />
	</bean>
	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
		<constructor-arg ref="jedisPoolConfig" />
		<constructor-arg value="192.168.1.5" />
	</bean>
	<bean id="cacheManager" class="com.huan.redis.springcache.RedisCacheManager">
		<property name="caches">
			<set>
				<bean class="com.huan.redis.springcache.RedisCache">
					<property name="jedisPool" ref="jedisPool" />
					<property name="name" value="usersCache" />
					<property name="timeouts" value="3600" />
				</bean>
				<bean class="com.huan.redis.springcache.RedisCache">
					<property name="jedisPool" ref="jedisPool" />
					<property name="name" value="booksCache" />
					<property name="timeouts" value="3600" />
				</bean>
			</set>
		</property>
	</bean>
</beans>

 注意:1. <cache:annotation-driven cache-manager="cacheManager"/>这一句用于开启spring的缓存注解

 

            2.redis.clients.jedis.JedisPool 用于配置redis的地址和端口,默认端口是6379,如果自己的redis不是这个端口,可以选择JedisPool中适当的构造方法进行配置

 

4.编写业务方法 -- UserService类中比较简单,就是UserServiceImpl中方法的申明。

 

package com.huan.redis.service;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * 测试业务员方法
 * @描述
 * @作者 huan
 * @时间 2016年6月26日 - 下午3:20:58
 */
@Service
public class UserServiceImpl implements UserService {
	/** 将数据放入到usersCache这个缓存中,缓存的key使用spirng的spel表达式获取值 */
	@Override
	@Cacheable(value = "usersCache", key = "#loginName")
	public String getUser(String loginName) {
		System.out.println("no user cache:" + loginName);
		return loginName;
	}
	@Override
	public String getUserNoCache(String loginName) {
		return getUser(loginName);
	}
	@Override
	@Cacheable(value = "booksCache", key = "#bookId")
	public String addBook(String bookId) {
		System.out.println("no book cache:" + bookId);
		return bookId;
	}
	/** 使usersCache中的缓存key为#loginName这个值的缓存失效 */
	@Override
	@CacheEvict(value = "usersCache", key = "#loginName")
	public void evictUser(String loginName) {
		System.out.println("evict cache loginName:" + loginName);
	}
}

 5.进行测试

 

 

 

 

posted @ 2016-06-26 15:37  huan1993  阅读(41)  评论(0编辑  收藏  举报