一、自定义注解开发Redis
1、java注解
参考:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
2、Redis-Spring配置
配置它两个如果顺利你不会抱任何错,不顺利的话错误停不下来。
1、Redis是集群还是单机,都没有问题,参见本博客的Redis集群搭建方式。
2、最主要的问题会发生在包冲突上,mvn dependece tree 命令可以解决,但是也可以简单点打开在IDE中打开看看依赖的一般是Spring的版本会冲突。尤其是引入:spring-data-redis包。
需要的基本配置:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.12.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
spring-data-common也可以不添加。
3、自定义注解开发
开发步骤:
1、创建注解
2、位注解添加切面
3、配置包扫描
参考:http://blog.youkuaiyun.com/cai_chinasoft/article/details/51680148
这篇博客适合入门学习,但是问题还是有的,在保存和删除缓存中使用了哈希数据结构,默认过期时间是永久,即:没有删除操作一直存在。哈希在删除上删除的数据很多粒度有些大。
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.你的切面所在的包" />
<context:annotation-config />
测试可以使用redis客户端查看数据。
二、RedisUtils开发
1、spring-redis配置文件,其实同上。但是要贴出了
<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="50" />
<property name="maxIdle" value="50" />
<property name="minIdle" value="10" />
</bean>
<bean id="jedisSentinelPool" class="redis.clients.jedis.JedisSentinelPool" destroy-method="destroy">
<constructor-arg name="masterName">
<value>master1</value>
</constructor-arg>
<constructor-arg name="sentinels">
<set value-type="java.lang.String">
<value>${redis.host}</value>
</set>
</constructor-arg>
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
</bean>
2、工具类
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
/**
*
*
*/
public class RedisUtils {
private static Logger logger = Logger.getLogger(RedisUtils.class);
/** 默认缓存时间 */
private static final int DEFAULT_CACHE_SECONDS = 60 * 60 * 1;// 单位秒 设置成一个钟
/** 连接池 **/
private static JedisSentinelPool jedisSentinelPool;
/**
* 释放redis资源
*
* @param jedis
*/
private static void releaseResource(Jedis jedis) {
if (jedis != null) {
jedisSentinelPool.returnResource(jedis);
}
}
/**
* 删除Redis中的所有key
*
* @param jedis
* @throws Exception
*/
public static void flushAll() {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.flushAll();
} catch (Exception e) {
logger.error("Cache清空失败:" + e);
} finally {
releaseResource(jedis);
}
}
/**
* 保存一个对象到Redis中(缓存过期时间:使用此工具类中的默认时间) . <br/>
*
* @param key
* 键 . <br/>
* @param object
* 缓存对象 . <br/>
* @return true or false . <br/>
* @throws Exception
*/
public static Boolean save(Object key, Object object) {
return save(key, object, DEFAULT_CACHE_SECONDS);
}
/**
* 保存一个对象到redis中并指定过期时间
*
* @param key
* 键 . <br/>
* @param object
* 缓存对象 . <br/>
* @param seconds
* 过期时间(单位为秒).<br/>
* @return true or false .
*/
public static Boolean save(Object key, Object object, int seconds) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.set(SerializeUtils.serialize(key), SerializeUtils.serialize(object));
jedis.expire(SerializeUtils.serialize(key), seconds);
return true;
} catch (Exception e) {
logger.error("Cache保存失败:" + e);
return false;
} finally {
releaseResource(jedis);
}
}
/**
* 根据缓存键获取Redis缓存中的值.<br/>
*
* @param key
* 键.<br/>
* @return Object .<br/>
* @throws Exception
*/
public static Object get(Object key) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
byte[] obj = jedis.get(SerializeUtils.serialize(key));
return obj == null ? null : SerializeUtils.unSerialize(obj);
} catch (Exception e) {
logger.error("Cache获取失败:" + e);
return null;
} finally {
releaseResource(jedis);
}
}
/**
* 根据缓存键清除Redis缓存中的值.<br/>
*
* @param key
* @return
* @throws Exception
*/
public static Boolean del(Object key) {
Jedis jedis = null;
try {
// System.out.println(key);
jedis = jedisSentinelPool.getResource();
jedis.del(SerializeUtils.serialize(key));
return true;
} catch (Exception e) {
logger.error("Cache删除失败:" + e);
return false;
} finally {
releaseResource(jedis);
}
}
/**
* 根据缓存键清除Redis缓存中的值.<br/>
*
* @param keys
* @return
* @throws Exception
*/
public static Boolean del(Object... keys) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.del(SerializeUtils.serialize(keys));
return true;
} catch (Exception e) {
logger.error("Cache删除失败:" + e);
return false;
} finally {
releaseResource(jedis);
}
}
/**
*
* @param key
* @param seconds
* 超时时间(单位为秒)
* @return
*/
public static Boolean expire(Object key, int seconds) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.expire(SerializeUtils.serialize(key), seconds);
return true;
} catch (Exception e) {
logger.error("Cache设置超时时间失败:" + e);
return false;
} finally {
releaseResource(jedis);
}
}
/**
* 添加一个内容到指定key的hash中
*
* @param key
* @param field
* @param value
* @return
*/
public static Boolean addHash(String key, Object field, Object value) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.hset(SerializeUtils.serialize(key), SerializeUtils.serialize(field), SerializeUtils.serialize(value));
return true;
} catch (Exception e) {
logger.error("Cache保存失败:" + e);
return false;
} finally {
releaseResource(jedis);
}
}
/**
* 从指定hash中拿一个对象
*
* @param key
* @param field
* @return
*/
public static Object getHash(Object key, Object field) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
byte[] obj = jedis.hget(SerializeUtils.serialize(key), SerializeUtils.serialize(field));
return SerializeUtils.unSerialize(obj);
} catch (Exception e) {
logger.error("Cache读取失败:" + e);
return null;
} finally {
releaseResource(jedis);
}
}
/**
* 从hash中删除指定filed的值
*
* @param key
* @param field
* @return
*/
public static Boolean delHash(Object key, Object field) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
long result = jedis.hdel(SerializeUtils.serialize(key), SerializeUtils.serialize(field));
return result == 1 ? true : false;
} catch (Exception e) {
logger.error("Cache删除失败:" + e);
return null;
} finally {
releaseResource(jedis);
}
}
/**
* 拿到缓存中所有符合pattern的key
*
* @param pattern
* @return
*/
public static Set<byte[]> keys(String pattern) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
Set<byte[]> allKey = jedis.keys(("*" + pattern + "*").getBytes());
return allKey;
} catch (Exception e) {
logger.error("Cache获取失败:" + e);
return new HashSet<byte[]>();
} finally {
releaseResource(jedis);
}
}
/**
* 获得hash中的所有key value
*
* @param key
* @return
*/
public static Map<byte[], byte[]> getAllHash(Object key) {
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
Map<byte[], byte[]> map = jedis.hgetAll(SerializeUtils.serialize(key));
return map;
} catch (Exception e) {
logger.error("Cache获取失败:" + e);
return null;
} finally {
releaseResource(jedis);
}
}
/**
* 判断一个key是否存在
*
* @param key
* @return
*/
public static Boolean exists(Object key) {
Jedis jedis = null;
Boolean result = false;
try {
jedis = jedisSentinelPool.getResource();
result = jedis.exists(SerializeUtils.serialize(key));
return result;
} catch (Exception e) {
logger.error("Cache获取失败:" + e);
return false;
} finally {
releaseResource(jedis);
}
}
public void setJedisSentinelPool(JedisSentinelPool jedisSentinelPool) {
RedisUtils.jedisSentinelPool = jedisSentinelPool;
}
public static JedisSentinelPool getJedisSentinelPool() {
return jedisSentinelPool;
}
}
3、实现cache接口
package com.lienbo.redis.rediscacheImpl;
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.stereotype.Component;
import wusc.edu.pay.common.utils.cache.redis.RedisUtils;
/**
*
* 实现spring的缓存接口
*/
@Component("redisCache")
public class RedisCache implements Cache {
/**缓存的命名属性**/
private String name;
public RedisUtils cache = new RedisUtils();
/**
* 清空所有的缓存
*/
public void clear() {
cache.flushAll();
}
@Override
public void evict(Object key) {
cache.del(key);
}
/**
* 根据Key值获得缓存数据
*/
public ValueWrapper get(Object key) {
ValueWrapper result = null;
Object thevalue = cache.get(key);
if (thevalue != null) {
result = new SimpleValueWrapper(thevalue);
}
return result;
}
@Override
public String getName() {
return name;
}
@Override
public Object getNativeCache() {
return cache;
}
/**添加缓存*/
public void put(Object arg0, Object arg1) {
cache.save(arg0, arg1,20000);
}
public RedisCache() {
}
public RedisCache(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
}
这里有对spring cache的详细说明
https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache//
4、缓存管理:
package com.lienbo.redis.rediscacheImpl;
import java.util.Collection;
import org.springframework.cache.Cache;
import org.springframework.cache.support.AbstractCacheManager;
/**
* 继承了 spring 内置的 AbstractCacheManager
* 管理 RedisCache 类缓存管理
*/
public class CacheManager<T extends Object> 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;
}
}
5、配置文件
<bean id="redisUtils" class="om.lienbo.RedisUtils">
<property name="jedisSentinelPool" ref="jedisSentinelPool" />
</bean>
<!-- redis caceh config end -->
<!-- generic cache manager -->
<cache:annotation-driven />
<!-- generic cache manager -->
<bean id="cacheManager" class="com.lienbo.CacheManager">
<property name="caches">
<set>
<bean
class="om.lienbo.RedisCache"
p:name="redisCache" />
</set>
</property>
</bean>
三、使用sprign cache实现redis缓存
其实原理同上:
1、配置文件
<cache:annotation-driven />
<!-- 缓存管理器 -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="com.config.SystemRedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<property name="name" value="default" />
<property name="timeout" value="${redis.timeout}" />
</bean>
<bean class="com.config.SystemRedisCache">
<property name="redisTemplate" ref="redisTemplate" />
<!--valeue 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 我是用来类名点方法名的方式 redisTemplate也可以配置多个-->
<property name="name" value="userService.queryUserById" />
<property name="timeout" value="${redis.timeout}" />
</bean>
</set>
</property>
</bean>
2、实现接口
这里有个坑:
注意注入的时候
三个redisTemplate name timeout 属性中 getName是实现接口的方法不要返回null,否则会报错的!
import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;
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.util.StringUtils;
public class SystemRedisCache implements Cache {
/**
* Redis
*/
private RedisTemplate<String, Object> redisTemplate;
/**
* 缓存名称
*/
private String name;
/**
* 超时时间
*/
private long timeout;
/*
* (non-Javadoc)
* @see org.springframework.cache.Cache#getName()
*/
@Override
public String getName() {
return this.name;
}
/*
* (non-Javadoc)
* @see org.springframework.cache.Cache#getNativeCache()
*/
@Override
public Object getNativeCache() {
// TODO Auto-generated method stub
return this.redisTemplate;
}
/*
* (non-Javadoc)
* @see org.springframework.cache.Cache#get(java.lang.Object)
*/
@Override
public ValueWrapper get(Object key) {
if (StringUtils.isEmpty(key)) {
return null;
} else {
final String finalKey;
if (key instanceof String) {
finalKey = (String) key;
} else {
finalKey = key.toString();
}
Object object = null;
object = redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key = finalKey.getBytes();
byte[] value = connection.get(key);
if (value == null) {
return null;
}
return SerializableObjectUtil.unserialize(value);
}
});
return (object != null ? new SimpleValueWrapper(object) : null);
}
}
/*
* (non-Javadoc)
* @see org.springframework.cache.Cache#get(java.lang.Object, java.lang.Class)
*/
@SuppressWarnings("unchecked")
@Override
public <T> T get(Object key, Class<T> type) {
if (StringUtils.isEmpty(key) || null == type) {
return null;
} else {
final String finalKey;
final Class<T> finalType = type;
if (key instanceof String) {
finalKey = (String) key;
} else {
finalKey = key.toString();
}
final Object object = redisTemplate.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
byte[] key = finalKey.getBytes();
byte[] value = connection.get(key);
if (value == null) {
return null;
}
return SerializableObjectUtil.unserialize(value);
}
});
if (finalType != null && finalType.isInstance(object) && null != object) {
return (T) object;
} else {
return null;
}
}
}
/*
* (non-Javadoc)
* @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object)
*/
@Override
public void put(final Object key, final Object value) {
if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
return;
} else {
final String finalKey;
if (key instanceof String) {
finalKey = (String) key;
} else {
finalKey = key.toString();
}
if (!StringUtils.isEmpty(finalKey)) {
final Object finalValue = value;
redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
public Boolean doInRedis(RedisConnection connection) {
connection.set(finalKey.getBytes(), SerializableObjectUtil.serialize(finalValue));
// 设置超时间
connection.expire(finalKey.getBytes(), timeout);
return true;
}
});
}
}
}
/*
* 根据Key 删除缓存
*/
@Override
public void evict(Object key) {
if (null != key) {
final String finalKey;
if (key instanceof String) {
finalKey = (String) key;
} else {
finalKey = key.toString();
}
if (!StringUtils.isEmpty(finalKey)) {
redisTemplate.execute(new RedisCallback<Long>() {
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.del(finalKey.getBytes());
}
});
}
}
}
/*
* 清楚系统缓存
*/
@Override
public void clear() {
}
public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setName(String name) {
this.name = name;
}
public long getTimeout() {
return timeout;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
}
3、使用方式
@Cacheable(
value = "userService.queryUserById",
key = "new String('commonService.queryUserById')+#id",
condition = "null != #id and #id.length() > 0")
public List<User> queryUserById(String id) {
return null;
}
4、附录
@Cacheable、@CachePut、@CacheEvict 注释介绍
通过上面的例子,我们可以看到 spring cache 主要使用两个注释标签,即 @Cacheable、@CachePut 和 @CacheEvict,我们总结一下其作用和配置方法。
表 1. @Cacheable 作用和配置方法
@Cacheable 的作用 | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 | |
---|---|---|
@Cacheable 主要的参数 | ||
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @Cacheable(value=”testcache”,key=”#userName”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
表 2. @CachePut 作用和配置方法
@CachePut 的作用 | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用 | |
---|---|---|
@CachePut 主要的参数 | ||
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @Cacheable(value=”testcache”,key=”#userName”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用 | 主要针对方法配置,能够根据一定的条件对缓存进行清空 | |
---|---|---|
@CacheEvict 主要的参数 | ||
value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @CachEvict(value=”testcache”,key=”#userName”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 | 例如: @CachEvict(value=”testcache”, condition=”#userName.length()>2”) |
allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如: @CachEvict(value=”testcache”,allEntries=true) |
beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | 例如: @CachEvict(value=”testcache”,befo |
四、@Configuration 方式配置
由于使用的不是Spring boot 注入属性的值有点不优雅!
import java.lang.reflect.Method;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
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.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* <p>
* RedisCacheConfig描述 redis集成springcache缓存使用
* </p>
*
* @author lienbo
* @since 0.0.1
*/
@Component
@EnableCaching
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
@Value(value = "${account.redis.hostName}")
private String hostName;
@Value(value = "${account.redis.port}")
private int port;
@Value(value = "${account.redis.timeout}")
private int timeout;
@Value(value = "${account.redis.userPool}")
private boolean reidsUserPool;
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
// ip地址
redisConnectionFactory.setHostName(hostName);
// 端口号
redisConnectionFactory.setPort(port);
// 超时时间
redisConnectionFactory.setTimeout(timeout);
// 是否开启线程池
redisConnectionFactory.setUsePool(reidsUserPool);
// 指定使用的数据库
redisConnectionFactory.setDatabase(2);
return redisConnectionFactory;
}
/**
* redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL,
JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/*
* (non-Javadoc)
*
* @see org.springframework.cache.annotation.CachingConfigurerSupport#
* keyGenerator()
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* <p>
* 方法说明
* </p>
*
* @action lienbo 2018年2月2日 下午6:07:24 描述
*
* @param redisTemplate
* @return CacheManager
*/
@Bean
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Sets the default expire time (in seconds) Long.
cacheManager.setDefaultExpiration(3000);
return cacheManager;
}
}
五、总结
以上三种方式是我见到过得redis应用场景,各有有缺,其实不推荐第二种,和代码没有分离,耦合比较深。
个人倾向第一种和第三种,如果完全是缓存,那么三很好有spring这个大树,而第一种可以扩展很多,可以
增加除了缓存的其他逻辑,这是再采用spring cache就显得不恰当了。