1.引入jar包
pom.xml中引入以下jar 注意版本 这个可以在maven仓库中查找spring-data-redis与jedis的版本对应关系,由于我这边用的是Spring4.X的版本,spring-data-redis必须使用2.X以下的版本 于是选取了1.X中最高的版本1.8.22.RELEASE 其对应jedis版本就是2.9.0。
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.22.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2.配置redis.porperties
一般配置以下参数即可:
# Redis settings
redis.host=127.0.0.1
redis.port=6379
redis.password=
# 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例
redis.maxIdle=400
#最大空连接数
redis.maxTotal=6000
# 表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间(毫秒),则直接抛出
redis.maxWaitMillis=1000
redis.blockWhenExhausted=true
#在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的
redis.testOnBorrow=true
#读超时时间
redis.timeout=100000
#defaultCacheExpireTime=60
#缓存默认保存时长 单位S
redis.expiration=36000
3.配置 spring-redis.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"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 加载配置文件 -->
<!-- <context:property-placeholder location="classpath:redis.properties" /> -->
<!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- 最大空连接数 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />
<!-- 返回连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- Spring-redis连接池管理工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<!-- IP地址 -->
<property name="hostName" value="${redis.host}" />
<!-- 端口号 -->
<property name="port" value="${redis.port}" />
<!-- 超时时间 默认2000-->
<property name="timeout" value="${redis.timeout}" />
<!-- 连接池配置引用 -->
<property name="poolConfig" ref="poolConfig" />
<!-- usePool:是否使用连接池 -->
<property name="usePool" value="true"/>
</bean>
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean>
<!-- 配置RedisCacheManager -->
<bean id="redisCacheManager" class="com.wxtec.dcms.neo4j.redis.ExtendedRedisCacheManager">
<constructor-arg name="redisOperations" ref="redisTemplate" />
<!-- 是否使用前缀 默认: -->
<property name="usePrefix" value="true" />
<!-- 默认有效期1h (60 * 60 = 3600秒) -->
<property name="defaultExpiration" value="${redis.expiration}" />
</bean>
<!-- 配置RedisCacheConfig -->
<bean id="redisCacheConfig" class="com.wxtec.dcms.neo4j.redis.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory" />
<constructor-arg ref="redisTemplate" />
<constructor-arg ref="redisCacheManager" />
</bean>
</beans>
4.applicationContext.xml 中增加配置:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- 这里支持多种寻址方式:classpath和file -->
<value>classpath:redis.porperties</value>
</list>
</property>
</bean>
<import resource="classpath:spring-redis.xml" />
5. 配置RedisCacheConfig
增加RedisCacheConfig.java 文件 配置redis
package com.wxtec.dcms.neo4j.redis;
import java.lang.reflect.Method;
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.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
/**
* 通过spring管理redis缓存配置
*
* @author Administrator
*
*/
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
private volatile JedisConnectionFactory jedisConnectionFactory;
private volatile RedisTemplate<String, String> redisTemplate;
private volatile RedisCacheManager redisCacheManager;
public RedisCacheConfig() {
super();
}
/**
* 带参数的构造方法 初始化所有的成员变量
*
* @param jedisConnectionFactory
* @param redisTemplate
* @param redisCacheManager
*/
public RedisCacheConfig(JedisConnectionFactory jedisConnectionFactory, RedisTemplate<String, String> redisTemplate,
RedisCacheManager redisCacheManager) {
this.jedisConnectionFactory = jedisConnectionFactory;
this.redisTemplate = redisTemplate;
this.redisCacheManager = redisCacheManager;
}
public JedisConnectionFactory getJedisConnecionFactory() {
return jedisConnectionFactory;
}
public RedisTemplate<String, String> getRedisTemplate() {
return redisTemplate;
}
public RedisCacheManager getRedisCacheManager() {
return redisCacheManager;
}
@Bean
public KeyGenerator customKeyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}
6.配置ExtendedRedisCacheManager (如果不需要对注解进行重写的话,则不需要使用自定义的RedisCacheManager,直接使用自带的就行,这里重写的目的是为了在注解中可以配置缓存超时时间)
ExtendedRedisCacheManager.java如下:
package com.wxtec.dcms.neo4j.redis;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
/**
* 重写redis缓存管理器
* <p>
* 重写 RedisCacheManager createCache 方法
* <p>
* 在缓存名字上添加过期时间表达式 如:cachename#60*60*24
* @author czk
*/
public class ExtendedRedisCacheManager extends RedisCacheManager {
private static final ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
private static final Pattern pattern = Pattern.compile("[+\\-*/%]");
/**
* 分隔符
*/
private char separator = '#';
public ExtendedRedisCacheManager(@SuppressWarnings("rawtypes") RedisOperations redisOperations) {
super(redisOperations);
}
@Override
@SuppressWarnings("unchecked")
protected RedisCache createCache(String cacheName) {
// 获取默认时间
long expiration = computeExpiration(cacheName);
int index = cacheName.indexOf(this.getSeparator());
if (index > 0) {
expiration = getExpiration(cacheName, index, expiration);
}
cacheName = cacheName.substring(0,index)+":";
return new RedisCache(cacheName, (isUsePrefix() ? getCachePrefix().prefix(cacheName) : null),
getRedisOperations(), expiration);
}
/**
* 计算缓存时间
* @param name 缓存名字 cacheName#60*60*24
* @param separatorIndex 分隔符位置
* @param defalutExp 默认缓存时间
* @return
*/
protected long getExpiration(final String name, final int separatorIndex, final long defalutExp) {
Long expiration = null;
String expirationAsString = name.substring(separatorIndex + 1);
try {
if (pattern.matcher(expirationAsString).find()) {
expiration = NumberUtils.toLong(scriptEngine.eval(expirationAsString).toString(), defalutExp);
} else {
expiration = NumberUtils.toLong(expirationAsString, defalutExp);
}
} catch (ScriptException e) {
e.printStackTrace();
}
return Objects.nonNull(expiration) ? expiration.longValue() : defalutExp;
}
public char getSeparator() {
return separator;
}
public void setSeparator(char separator) {
this.separator = separator;
}
}
到此,配置已经全部配置完了 直接在方法中使用
@Cacheable(value = "neo4jCache#3600*24*7", key = "#id") 等注解即可使用缓存
另:本次配置没用使用redis集群,如果使用集群,需要在spring-redis.xml中和RedisCacheConfig.java中进行集群的配置即可,下次再把这部分补上。