SpringBoot Redis Cache

文章介绍了Spring高版本中使用注解进行缓存管理的技术,包括@EnableCaching、@Cacheable、@CacheEvict、@CachePut等关键注解的用途。同时,文章详细展示了如何配置基于Redis的缓存管理器,包括自定义KeyGenerator、设置序列化策略以及不同缓存的超时时间。此外,还提到了SpringDataRedis在Redis缓存技术中的应用。
摘要由CSDN通过智能技术生成

知识点

Spring高版本引入了Cache的注解技术。该技术是一种规范,官方支持的实现包括Generic、JCache(JSR-107)、(EhCache 3,Hazelcast,Infinispan,and others)、EhCache 2.x、Hazelcast、Infinispan、Couchbase、Redis、Caffeine、Simple等。

Redis的Cache技术,底层使用的是Spring Data Redis

Cache技术主要有以下注解@EnableCaching@Cacheable@CacheEvict@CachePut@Caching@CacheConfig,这些注解支持Spring SPEL表达式

注解详解

@EnableCaching:作用于配置类,用来打开SpringBoot的Cache自动装配
@Cacheable:表示被调用的方法先要去缓存中查询,如果命中则返回缓存中的内容,否则调用方法返回并将返回结果存入缓存。
@CacheEvict:表示方法结束后删除缓存,可以通过beforeInvocation=true设置方法执行前删除缓存
@CachePut:用来更新缓存,旧的值会被覆盖,方法一定会执行
@Caching:多个缓存符合操作
@CacheConfig:标注在类上,对类中的方法统一设置缓存操作

Cache配置类

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 com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
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.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 基于Redis的缓存配置
 *
 * @author √Angelの爱灬
 * @date 2023/5/29
 */
@Configuration
@EnableCaching
public class SpringCacheRedisConfig {

    @Value("${spring.application.name}")
    private String appName;

    /**
     * Cache key generator. Used for creating a key based on the given method (used as context) and its parameters.<br/>
     * className:methodName:param1-param2...
     *
     * @return KeyGenerator
     */
    @Bean
    public KeyGenerator wiselyKeyGenerator() {
        return (object, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(object.getClass().getName()).append(":");
            sb.append(method.getName()).append(":");
            for (Object obj : params) {
                sb.append(obj.toString()).append("-");
            }
            return sb.substring(0, sb.length() - 1);
        };
    }

    /**
     * CacheManager backed by a Redis cache.
     *
     * @param factory Thread-safe factory of Redis connections.
     * @return RedisCacheManager
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        return RedisCacheManager.builder(factory)
                // 默认缓存配置
                .cacheDefaults(defaultCacheConfig(Duration.ofDays(1)))
                // 针对于指定key做自定义操作
                .withInitialCacheConfigurations(initCacheConfig())
                .transactionAware()
                .build();
    }

    /**
     * 设置redis中value的序列化方式
     *
     * @return Jackson2JsonRedisSerializer
     */
    private Jackson2JsonRedisSerializer<Object> redisValueSerializer() {
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        // 指定序列化的作用域(field、get()、set()等)和作用域的访问修饰符
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型,类不可以是被final修饰的
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        // 设置时间格式序列化及反序列化
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DatePattern.NORM_DATE_FORMATTER));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DatePattern.NORM_TIME_FORMATTER));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DatePattern.NORM_DATE_FORMATTER));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DatePattern.NORM_TIME_FORMATTER));
        objectMapper.registerModule(javaTimeModule);
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }

    /**
     * 设置默认缓存配置
     *
     * @param duration key的有效时间(Duration.ZERO为永不过期)
     * @return RedisCacheConfiguration
     */
    private RedisCacheConfiguration defaultCacheConfig(Duration duration) {
        return RedisCacheConfiguration.defaultCacheConfig()
                // 格式化cacheName,默认为 cacheName::
                .computePrefixWith(cacheName -> String.format("%s:%s:", appName, cacheName))
                // key的默认超时时间
                .entryTtl(duration)
                // key的序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
                // value的序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisValueSerializer()))
                // 不缓存空值
                .disableCachingNullValues();
    }

    /**
     * SpringBoot Cache 中特殊key的配置,这里只针对某些key设置超时时间
     *
     * @return key——对应的配置
     */
    private Map<String, RedisCacheConfiguration> initCacheConfig() {
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>(16);
        configMap.put("user", defaultCacheConfig(Duration.ofHours(8)));
        configMap.put("cacheable", defaultCacheConfig(Duration.ZERO));
        return configMap;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值