项目中很多地方需要用到注解,这里我们讲一下springframework包帮我们封装的@Cacheable注解。
基础工作
-
在使用缓存功能前,我们需要配置一些缓存的基本信息及配置。在SpringBoot项目中,redis的缓存也相当简单。
-
首先在application.properties中配置我们要连接的Redis连接,auth等配置
-
application.properties片段
#Redis
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=0
spring.redis.pool.max-active=8
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-wait=-1
- RedisConfig.java
package com.shanyuan.platform.ms.base.cache.config;
import java.util.HashMap;
import java.util.Map;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.shanyuan.platform.ms.base.cache.serializer.FastJson2JsonRedisSerializer;
import com.shanyuan.platform.ms.base.common.CommonRedisKey;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{
//缓存管理器
@Bean
public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisCacheManager cacheManager = null;
if(factory instanceof JedisConnectionFactory) {
JedisConnectionFactory jcf = (JedisConnectionFactory) factory;
JedisPoolConfig npc = (JedisPoolConfig) jcf.getPoolConfig().clone();
JedisConnectionFactory njcf= new JedisConnectionFactory(npc);
njcf.setHostName(jcf.getHostName());
njcf.setPort(jcf.getPort());
njcf.setPassword(jcf.getPassword());
njcf.setTimeout(jcf.getTimeout());
njcf.setDatabase(0);
njcf.setUsePool(true);
njcf.afterPropertiesSet();
@SuppressWarnings("rawtypes")
RedisTemplate ntemplate = new StringRedisTemplate(njcf);
setSerializer(ntemplate);//设置序列化工具
ntemplate.afterPropertiesSet();
cacheManager = new RedisCacheManager(ntemplate);
}
if(cacheManager==null) {
cacheManager = new RedisCacheManager(redisTemplate);
}
//设置缓存过期时间
cacheManager.setDefaultExpiration(30);
return cacheManager;
}
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){
if(factory instanceof JedisConnectionFactory) {
JedisConnectionFactory jcf = (JedisConnectionFactory) factory;
jcf.setDatabase(3);
}
StringRedisTemplate template = new StringRedisTemplate(factory);
setSerializer(template);//设置序列化工具
template.afterPropertiesSet();
return template;
}
private void setSerializer(RedisTemplate template){
FastJson2JsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer(Object.class);
template.setValueSerializer(fastJsonRedisSerializer);
template.setKeySerializer(new StringRedisSerializer());
}
}
-
数据在存到redis中和取出来展示,是需要序列化和反序列化的,所以需要配置序列化工具。
-
FastJson2JsonRedisSerializer.java
package com.shanyuan.platform.ms.base.cache.serializer;
import java.nio.charset.Charset;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
this.clazz = clazz;
}
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}
}