Spring集成Redis缓存实现

来源:互联网 发布:淘宝汽车商城 编辑:程序博客网 时间:2024/06/11 21:14

下面我们来实现Spring集成Redis缓存如何实现的。一般有一下几个步骤

 

Spring集成Redis的几个步骤:1、搭建Redis 服务器环境(windows环境下搭建\Linux环境下搭建)2、启动Redis服务3、maven项目中添加依赖4、配置Spring对Redis相关bean的引用5、配置Redis基本属性6、编辑实现RedisTemplate的实现工具类7、遇到的问题

1、搭建Redis服务器环境

     在Redis官网上下载的包redis-4.0.1.tar,只能在linux环境下搭建,无法在windows环境下使用。但是呢我们只有windows环境,想着弄个虚拟机来模拟,但是感觉有点费事儿麻烦,主要还是电脑配置有点低,所以嘿嘿,就想办法找了个能在windows环境下实现Redis服务的办法。废话不多说先说下Linux换下如何装redis

Linux:(1)、下载安装包解压编译

         
$ wget http://download.redis.io/releases/redis-2.8.3.tar.gz$ tar xzf redis-2.8.3.tar.gz$ cd redis-2.8.3$ make

  (2)、编译完成后,在Src目录下,有四个可执行文件redis-server、redis-benchmark、redis-cli和redis.conf。然后拷贝到一个目录下
mkdir /usr/rediscp redis-server  /usr/rediscp redis-benchmark /usr/rediscp redis-cli  /usr/rediscp redis.conf  /usr/rediscd /usr/redis

 (3)、开始启动Redis服务

$ redis-server   redis.conf
(4)、用客户端测试下是否启动成功

$ redis-cliredis> set uo barOKredis> get uo"bar"
下面是Redis的Windows下安装,由于官网上不支持Redis安装,就有牛人造了一个能在windows环境下安装的,redis-2.4.5-win32-win64.zip,里面有32位和64位请根据自己的需求安装,下面是安装步骤:

1、下载包redis-2.4.5-win32-win64.zip.链接:https://pan.baidu.com/s/1pL5gywV

2、开始解压

在d盘下新建d:\lamp\redis目录文件夹。1、把64位包里的文件全部拷贝到redis目录下2、接下来在cmd控制台切换到redis目录下,或者在redis目录下按shift+右击   用命令行打开3、redis-server.exe redis.conf4、 此时表示服务器开始成功,一定不要关闭该控制台,否则后面就无法连接成功了!!!


3、链接测试下

1、重新打开一个新的cmd控制台切换到redis目录2、执行: redis-cli.exe -h 127.0.0.1 -p 6379此时,表示redis连接成功了。我们可以在redis.conf中配置    (1)port 6379 //端口    (2)bind 127.0.0.1 //环回网络此时,就不用添加-h -p参数了,使用redis-cli.exe即可连接成功

这样我们就已经在windows环境下搭建好redis服务器了,第一个cmd要一直保留,第二个cmd只是测试用,关掉后不影响redis服务

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、在Maven+Spring项目中添加相关依赖

<!-- redis 依赖开始 --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.6.1.RELEASE</version></dependency><!-- redis 依赖结束 -->

注意Spring-data-redis版本问题,一开始用的是最新的版本2.4.0启动一直报版本太高不适配,具体哪里不适配没找到。我们可以用稍微低版本的稳定版的就可以。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4、配置Spring对Redis相关bean的引用

<?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        classpath:org/springframework/beans/factory/xml/spring-beans-4.2.xsd"><!-- ↓↓↓↓↓redis 的配置信息 ↓↓↓↓↓ --><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><!-- 最大连接数 --><property name="maxTotal" value="${redis.pool.maxTotal}"></property><!-- 最大空闲数:空闲链接数大于maxIdle时,将进行回收 --><property name="maxIdle" value="${redis.pool.maxIdle}"></property><!-- 最大等待时间:单位ms --><property name="maxWaitMillis" value="${redis.pool.maxWait}"></property><!-- 逐出连接的最小空闲时间 :单位ms --><property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}"></property><!-- 每次逐出检查时 逐出的最大数目 --><property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}"></property><!-- 逐出扫描的时间间隔(毫秒) --><property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}"></property></bean><!-- ↑↑↑↑↑redis 的配置信息↑↑↑↑↑ --><!-- ↓↓↓↓↓redis 服务器中心 ↓↓↓↓↓ --><bean id="jedisConnectionFactory"class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"destroy-method="destroy"><property name="poolConfig" ref="jedisPoolConfig"></property><!-- Redis服务器地址 --><property name="hostName" value="${redis.host}"></property><!-- 服务端口 --><property name="port" value="${redis.port}"></property><!-- 授权密码 --><property name="password" value=""></property><!-- 超时时间:单位ms --><property name="timeout" value="${redis.timeout}"></property><!--启用用户线程池 --><property name="usePool" value="true"></property></bean><!-- ↑↑↑↑↑redis 服务器中心 ↑↑↑↑↑ --><!-- ☂☂☂redis操作模板,面向对象的模板☂ ☂☂ --><bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate"><property name="connectionFactory" ref="jedisConnectionFactory"></property><property name="keySerializer"><beanclass="org.springframework.data.redis.serializer.StringRedisSerializer" /></property><property name="valueSerializer"><beanclass="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /></property></bean><!-- ♨♨♨redis操作模板,面向对象的模板♨♨♨ --><bean id="redisCache" class="com.zpl.cache.rediscache.RedisCache"><property name="jedisTemplate" ref="jedisTemplate"></property></bean><bean id="cacheManage" class="com.zpl.cache.CacheManage"><property name="cache" ref="redisCache"></property></bean></beans>
redis.properties

redis.host=127.0.0.1redis.port=6379redis.timeout=3000#redis.password=123//没有密码就不用设置redis.pool.maxTotal=200redis.pool.maxIdle=20redis.pool.minIdle=5redis.pool.maxWait=15000redis.pool.minEvictableIdleTimeMillis=30000redis.pool.numTestsPerEvictionRun=3redis.pool.timeBetweenEvictionRunsMillis=60000redis.pool.testOnBorrow=true

dispatcher-servlet-xml应用spring-redis.xml

<!-- Spring中引入其他配置文件 -->    <import resource="classpath*:/spring/spring-redis.xml" />
配置以及引用我们就大致配置好了,maven update 更新下
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6、编辑实现RedisTemplate的实现工具类(这一块想了解最好是去学习下RedisTemplate模板,和jdbcTemplate一样是Spring提供集成的模板)

package com.zpl.cache.rediscache;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.serializer.support.SerializingConverter;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.RedisSerializer;import com.zpl.cache.Cache;/** * 实现缓存功能 * <p> * 通过jedisTemplate来实现将我们的数据以及数据结构保存到缓存redis中, <br> * 这个是由Spring封装的模板 *  * @author zhangpengliang * */public class RedisCache implements Cache {private RedisTemplate<String, Object> jedisTemplate;@Value("${redis.host}")private String redishost;/** * 按键值的方式存储 *  * @param key *            键 * @param value *            值 */public void put(String key, Object value) {jedisTemplate.opsForValue().set(key, value);}@Overridepublic void put(String key, Object value, int timeout) {jedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);// TimeUnit.SECONDS秒}@Overridepublic Object get(String key) {return jedisTemplate.opsForValue().get(key);}/** * 获取key对应的值,并转换为指定类型 *  * @param key *            键 * @param requiredType *            类型 * @return */@SuppressWarnings("unchecked")public <T> T get(String key, Class<T> requiredType) {return (T) jedisTemplate.opsForValue().get(key);}/** * 移出 *  * @param key */public void remove(String key) {jedisTemplate.delete(key);}@Overridepublic Set<String> keys(String pattern) {return jedisTemplate.keys(pattern);}@Overridepublic void putHash(String key, Map<?, ?> value) {jedisTemplate.opsForHash().putAll(key, value);}/** * 以Hash的方式将对象存入缓存中 *  * @param key *            缓存中的key * @param hashKey *            hash中的key * @param value *            hash中的value */public void putHash(String key, String hashKey, Object value) {jedisTemplate.opsForHash().put(key, hashKey, value);}@Overridepublic Map<?, Object> getHash(String key) {// TODO Auto-generated method stubreturn jedisTemplate.opsForHash().entries(key);}@Overridepublic Object getHash(String key, String hashKey) {// TODO Auto-generated method stubreturn jedisTemplate.opsForHash().get(key, hashKey);}@SuppressWarnings("unchecked")@Overridepublic <T> T getHash(String key, String hashKey, Class<T> requiredType) {// TODO Auto-generated method stubreturn (T) jedisTemplate.opsForHash().get(key, hashKey);}@Overridepublic void removeHash(String key) {jedisTemplate.opsForHash().delete(key);}@Overridepublic void removeHash(String key, Object... hashKeys) {jedisTemplate.opsForHash().delete(key, hashKeys);}@Overridepublic void put(final Map<String, ?> data) {RedisCallback<Map<String, ?>> pipCallBack = new RedisCallback<Map<String, ?>>() {@Overridepublic Map<String, ?> doInRedis(RedisConnection connection) throws DataAccessException {connection.openPipeline();RedisSerializer<String> rs = jedisTemplate.getStringSerializer();SerializingConverter sc = new SerializingConverter();for (String key : data.keySet()) {connection.append(rs.serialize(key), sc.convert(data.get(key)));}connection.closePipeline();return null;}};jedisTemplate.execute(pipCallBack);}public boolean zAdd(String key, Object value) {return this.zAdd(key, value, System.currentTimeMillis());}public boolean zAdd(String key, Object value, double score) {return jedisTemplate.opsForZSet().add(key, value, score);}public Set<Object> zGetByRank(String key, long start, long end) {return jedisTemplate.opsForZSet().range(key, start, end);}public Set<Object> zGetByScore(String key, double min, double max) {return jedisTemplate.opsForZSet().rangeByScore(key, min, max);}public Long zRemove(String key, Object... values) {return jedisTemplate.opsForZSet().remove(key, values);}public Long zRemoveByRank(String key, long start, long end) {return jedisTemplate.opsForZSet().removeRange(key, start, end);}public Long zRemoveByScore(String key, double min, double max) {return jedisTemplate.opsForZSet().removeRangeByScore(key, min, max);}public RedisTemplate<String, Object> getJedisTemplate() {return jedisTemplate;}public void setJedisTemplate(RedisTemplate<String, Object> jedisTemplate) {this.jedisTemplate = jedisTemplate;}}
CacheManage.java是我们的工具类相当于
package com.zpl.cache;import java.util.Map;import java.util.Set;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Component;/** * 缓存管理工具 * @author zhangpengliang * */public class CacheManage {private static Cache cache;public static Cache getCache() {return cache;}@Autowiredpublic static void setCache(Cache cache) {CacheManage.cache = cache;}/*public CacheManage(Cache cache){CacheManage.cache=cache;}*//** * 按键值的方式存储 * @param key * @param value */public static void put(String key, Object value) {CacheManage.cache.put(key, value);}/** * 按键值方式存储,可以设置超时 *  * @param key *            键 * @param value *            值 * @param timeout *            超时时间 */public static void put(String key, Object value, int timeout) {CacheManage.cache.put(key, value, timeout);}/** * 获取key对应的值 *  * @param key *            键 * @return */public static Object get(String key){return CacheManage.cache.get(key);}/** * 获取key对应的值,并转换为指定类型 *  * @param key *            键 * @param requiredType *            类型 * @return */public static <T> T get(String key,Class<T> requiredType){return CacheManage.cache.get(key, requiredType);}/** * 移除对应值 *  * @param key *            键 */public static void remove(String key){CacheManage.cache.remove(key);}//为手动public static Set<String> keys(String pattern) {return CacheManage.cache.keys(pattern);}public static void putHash(String key, Map<?, ?> value) {CacheManage.cache.putHash(key, value);}public static void putHash(String key, String hashKey, Object value) {CacheManage.cache.putHash(key, hashKey, value);}public static Map<?, ?> getHash(String key) {return CacheManage.cache.getHash(key);}public static Object getHash(String key, String hashKey) {return CacheManage.cache.getHash(key, hashKey);}public static <T> T getHash(String key, String hashKey, Class<T> requiredType) {return CacheManage.cache.getHash(key, hashKey, requiredType);}public static void removeHash(String key) {CacheManage.cache.removeHash(key);}public static void removeHash(String key, Object... hashKeys) {CacheManage.cache.removeHash(key, hashKeys);}/** * 使用pipeline的方式插入批量数据 * <p> * 使用get相关方法获取,请勿使用getHash方法取值 *  * @param data *            需要被插入的批量数据 */public static void put(Map<String, ?> data) {CacheManage.cache.put(data);}public boolean zAdd(String key, Object value) {return CacheManage.cache.zAdd(key, value);}public boolean zAdd(String key, Object value, double score) {return CacheManage.cache.zAdd(key, value, score);}public Set<Object> zGetByRank(String key, long start, long end) {return CacheManage.cache.zGetByRank(key, start, end);}public Set<Object> zGetByScore(String key, double min, double max) {return CacheManage.cache.zGetByScore(key, min, max);}public Long zRemove(String key, Object... values) {return CacheManage.cache.zRemove(key, values);}public Long zRemoveByRank(String key, long start, long end) {return CacheManage.cache.zRemoveByRank(key, start, end);}public Long zRemoveByScore(String key, double min, double max) {return CacheManage.cache.zRemoveByScore(key, min, max);}}

7、遇到的问题:

使用注解无法装配实例。如:cacheManage中的Cache实例没法装配解决办法--添加set 方法并在xml里添加配置

在cacheMange中用注解无法获取到cache接口的实例。

但是我用xml的方式就可以实现:去掉上面的注解用下面的xml方式



很是费解;可能是哪里注解没有写对吧可能,在详细了解注解之后我再看下这个问题。。。


下面我们就测试下看看




 
原创粉丝点击