实战出真知, 作文以记之.
解决的主要痛点
以 SpringBoot2.0.2 为背景
通用的序列化和反序列化设置
使用 Jackson2JsonRedisSerializer 进行序列化与反序列化.
解决缓存中的乱码问题
详细的使用说明
齐全的使用示例
创建 Spring Boot 工程
略, 详细步骤可参考使用 STS 创建 Spring Boot 项目.
添加 Maven 依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- </dependency>
- <dependency>
- <groupId>Redis.clients</groupId>
- <artifactId>jedis</artifactId>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- </dependency>
Redis 的配置参数
在 application.properties 中加入以下配置参数
- # 缓存时长, 单位秒
- cache.default-exp=72
- # 数据库设置
- spring.Redis.database=0
- # 宿主机 IP
- spring.Redis.host=127.0.0.1
- # 端口号
- spring.Redis.port=6379
- # 密码
- spring.Redis.password=Redis
- # 连接超时时间 单位 ms(毫秒)
- spring.Redis.timeout=3000
- # 连接池中的最大空闲连接, 默认值也是 8
- spring.Redis.lettuce.pool.max-idle=100
- # 连接池中的最小空闲连接, 默认值也是 0
- spring.Redis.lettuce.pool.min-idle=50
- # 如果赋值为 - 1, 则表示不限制
- spring.Redis.lettuce.pool.max-wait=2000
使用注解配置 Redis
创建一个名为 RedisConfig 的 class 并继承 CachingConfigurerSupport, 注意需要在 class 上添加 @Configuration 和 @EnableCaching 注解.
- import java.lang.reflect.Method;
- import java.time.Duration;
- 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.RedisCacheConfiguration;
- import org.springframework.data.Redis.cache.RedisCacheManager;
- import org.springframework.data.Redis.connection.RedisConnectionFactory;
- import org.springframework.data.Redis.core.RedisTemplate;
- import org.springframework.data.Redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.Redis.serializer.RedisSerializationContext;
- import org.springframework.data.Redis.serializer.RedisSerializer;
- import org.springframework.data.Redis.serializer.StringRedisSerializer;
- import com.alibaba.fastjson.JSON;
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.ObjectMapper;
- @Configuration
- @EnableCaching
- public class RedisConfig extends CachingConfigurerSupport {
- @Value("${cache.default-exp}")
- private long exps;
- @Value("${spring.redis.host}")
- private String host;
- @Value("${spring.redis.port}")
- private int port;
- @Value("${spring.redis.timeout}")
- private int timeout;
- @Value("${spring.redis.password}")
- private String password;
- @Value("${spring.redis.lettuce.pool.min-idle}")
- private int minIdle;
- @Value("${spring.redis.lettuce.pool.max-idle}")
- private int maxIdle;
- @Value("${spring.redis.lettuce.pool.max-wait}")
- private long maxWaitMillis;
- @Bean
- public KeyGenerator keyGenerator() {
- return new KeyGenerator() {
- @Override
- public Object generate(Object target, Method method, Object... params) {
- StringBuffer sb = new StringBuffer();
- sb.append(target.getClass().getName());
- sb.append(method.getName());
- for (Object obj : params) {
- sb.append(obj.toString());
- }
- return sb.toString();
- }
- };
- }
- /**
- * RedisTemplate 配置
- *
- * @param redisConnectionFactory
- * @return
- */
- @Bean
- public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
- RedisTemplate<Object, Object> template = new RedisTemplate<>();
- template.setConnectionFactory(redisConnectionFactory);
- // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 Redis 的 value 值
- Jackson2JsonRedisSerializer<JSON> serializer = new Jackson2JsonRedisSerializer<JSON>(JSON.class);
- ObjectMapper mapper = new ObjectMapper();
- mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- serializer.setObjectMapper(mapper);
- template.setValueSerializer(serializer);
- template.setHashValueSerializer(serializer);
- // 使用 StringRedisSerializer 来序列化和反序列化 Redis 的 key 值
- template.setKeySerializer(new StringRedisSerializer());
- template.afterPropertiesSet();
- return template;
- }
- @Bean
- public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
- // 生成一个默认配置, 通过 config 对象即可对缓存进行自定义配置
- RedisSerializer<String> redisSerializer = new StringRedisSerializer();
- // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 Redis 的 value 值
- Jackson2JsonRedisSerializer<JSON> serializer = new Jackson2JsonRedisSerializer<JSON>(JSON.class);
- // 配置序列化
- RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
- config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer));
- config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
- // 设置缓存的默认过期时间
- config.entryTtl(Duration.ofSeconds(exps));
- // 不缓存空值
- config.disableCachingNullValues();
- RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
- return cacheManager;
- }
- }
缓存使用示例
分别对 @Cacheable,@CachePut 和 @CacheEvict 进行了举例.
- @Cacheable(value = "users",key = "#collection.concat(#user.id)")
- public void create(String collection, JSONObject user) {
- //do something
- }
- @CacheEvict(value = "users",key = "#collection.concat(#id)")
- public void delete(String collection, String id) {
- //do something
- }
- @Cacheable(value = "users",key = "#collection.concat(#id)")
- public JSONObject getOne(String collection, String id) {
- //do something
- }
注意事项
要缓存的 Java 对象必须实现 Serializable 接口
在 CacheManager 对象中 设置缓存过期时间, 否则缓存对象将永不过期
缓存 key 必须为 string 类型的值, 否则需要进行类型转换
来源: http://www.jianshu.com/p/81af79f982c3