下面我们来实现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
mkdir /usr/redis
cp redis-server /usr/redis
cp redis-benchmark /usr/redis
cp redis-cli /usr/redis
cp redis.conf /usr/redis
cd /usr/redis
$ redis-server redis.conf
$ redis-cli
redis> set uo bar
OK
redis> get uo
"bar"
在d盘下新建d:\lamp\redis目录文件夹。
1、把64位包里的文件全部拷贝到redis目录下
2、接下来在cmd控制台切换到redis目录下,或者在redis目录下按shift+右击
用命令行打开
3、redis-server.exe redis.conf
4、 此时表示服务器开始成功,一定不要关闭该控制台,否则后面就无法连接成功了!!!
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即可连接成功
<!-- 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 依赖结束 -->
<?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">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="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.host=127.0.0.1
redis.port=6379
redis.timeout=3000
#redis.password=123//没有密码就不用设置
redis.pool.maxTotal=200
redis.pool.maxIdle=20
redis.pool.minIdle=5
redis.pool.maxWait=15000
redis.pool.minEvictableIdleTimeMillis=30000
redis.pool.numTestsPerEvictionRun=3
redis.pool.timeBetweenEvictionRunsMillis=60000
redis.pool.testOnBorrow=true
<!-- Spring中引入其他配置文件 -->
<import resource="classpath*:/spring/spring-redis.xml" />
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);
}
@Override
public void put(String key, Object value, int timeout) {
jedisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);// TimeUnit.SECONDS秒
}
@Override
public 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);
}
@Override
public Set<String> keys(String pattern) {
return jedisTemplate.keys(pattern);
}
@Override
public 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);
}
@Override
public Map<?, Object> getHash(String key) {
// TODO Auto-generated method stub
return jedisTemplate.opsForHash().entries(key);
}
@Override
public Object getHash(String key, String hashKey) {
// TODO Auto-generated method stub
return jedisTemplate.opsForHash().get(key, hashKey);
}
@SuppressWarnings("unchecked")
@Override
public <T> T getHash(String key, String hashKey, Class<T> requiredType) {
// TODO Auto-generated method stub
return (T) jedisTemplate.opsForHash().get(key, hashKey);
}
@Override
public void removeHash(String key) {
jedisTemplate.opsForHash().delete(key);
}
@Override
public void removeHash(String key, Object... hashKeys) {
jedisTemplate.opsForHash().delete(key, hashKeys);
}
@Override
public void put(final Map<String, ?> data) {
RedisCallback<Map<String, ?>> pipCallBack = new RedisCallback<Map<String, ?>>() {
@Override
public 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;
}
}
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;
}
@Autowired
public 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);
}
}