package com.teriteri.backend.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; 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.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.lang.reflect.Method; @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Value("${spring.redis.jedis.pool.max-idle}") private int maxIdle; @Value("${spring.redis.jedis.pool.max-wait}") private long maxWaitMillis; /** * 创建并配置一个 Jedis 连接池 * @return */ @Bean @SuppressWarnings("all") public JedisPool redisPoolFactory() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(maxIdle); jedisPoolConfig.setMaxWaitMillis(maxWaitMillis); return new JedisPool(jedisPoolConfig, host, port, timeout); } /** * 缓存键生成器,在这个项目中用不到,我更倾向自己手动命名,如 user:1:age * @return */ @Bean @SuppressWarnings("all") public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } /** * Redis 缓存管理器 * @param connectionFactory * @return */ @Bean @SuppressWarnings("all") public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).build(); return redisCacheManager; } /** * 编写自己的 redisTemplate,用于与 Redis 进行交互,配置了json格式存储,序列化与反序列化 * @param redisConnectionFactory * @return */ @Bean @SuppressWarnings("all") public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { // 为了方便自己开发,一般直接使用 RedisTemplate template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // 序列化配置 // json的序列化 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // 用json序列化任意对象类 ObjectMapper om = new ObjectMapper(); // 对象类序列化过程中用 ObjectMapper 进行转义 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // String的序列化 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用了String的序列化方式 template.setKeySerializer(stringRedisSerializer); // hash的key也采用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); // value序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); // hash的value序列化方式采用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } /** * 一个专门用于操作 Redis 字符串类型的模板,它是 RedisTemplate 的子类,只支持字符串数据的存储和检索 * @param factory * @return */ @Bean @SuppressWarnings("all") public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); stringRedisTemplate.setConnectionFactory(factory); return stringRedisTemplate; } }