SpringCache

目录

SpringCache

引入

自动配置

自定义配置

注解

@Cacheable

@CacheEvict​​

[sync = true](#sync = true)


SpringCache

集成与管理缓存,它通过声明式注解和统一的 API,将缓存逻辑与业务逻辑解耦,支持多种缓存实现(如 Redis、Ehcache、Caffeine 等),并提供了灵活的配置选项。

引入

XML 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
复制代码
@EnableCaching开启缓存

自动配置

复制代码
CacheAutoConfiguration 依据缓存类型,自动配置缓存。
复制代码
CacheConfigurations 映射 相应的缓存配置
java 复制代码
    static {
        Map<CacheType, Class<?>> mappings = new EnumMap(CacheType.class);
        mappings.put(CacheType.GENERIC, GenericCacheConfiguration.class);
        mappings.put(CacheType.EHCACHE, EhCacheCacheConfiguration.class);
        mappings.put(CacheType.HAZELCAST, HazelcastCacheConfiguration.class);
        mappings.put(CacheType.INFINISPAN, InfinispanCacheConfiguration.class);
        mappings.put(CacheType.JCACHE, JCacheCacheConfiguration.class);
        mappings.put(CacheType.COUCHBASE, CouchbaseCacheConfiguration.class);
        mappings.put(CacheType.REDIS, RedisCacheConfiguration.class);
        mappings.put(CacheType.CAFFEINE, CaffeineCacheConfiguration.class);
        mappings.put(CacheType.SIMPLE, SimpleCacheConfiguration.class);
        mappings.put(CacheType.NONE, NoOpCacheConfiguration.class);
        MAPPINGS = Collections.unmodifiableMap(mappings);
    }
复制代码
RedisCacheConfiguration 为每一个缓存"分区"提供初始化,并返回Manager
java 复制代码
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) {
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader()));
        List<String> cacheNames = this.cacheProperties.getCacheNames();
        if (!cacheNames.isEmpty()) {
            builder.initialCacheNames(new LinkedHashSet(cacheNames));
        }

        return (RedisCacheManager)this.customizerInvoker.customize(builder.build());
    }
复制代码
Manager为每一个分区进行默认配置defaultCacheConfiguration
java 复制代码
        public RedisCacheManagerBuilder initialCacheNames(Set<String> cacheNames) {
            Assert.notNull(cacheNames, "CacheNames must not be null!");
            Map<String, RedisCacheConfiguration> cacheConfigMap = new LinkedHashMap(cacheNames.size());
            cacheNames.forEach((it) -> {
                RedisCacheConfiguration var10000 = (RedisCacheConfiguration)cacheConfigMap.put(it, this.defaultCacheConfiguration);
            });
            return this.withInitialCacheConfigurations(cacheConfigMap);
        }
复制代码
redisCacheConfiguration 若为空,这采用默认配置
java 复制代码
    private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(ClassLoader classLoader) {
        if (this.redisCacheConfiguration != null) {
            return this.redisCacheConfiguration;
        } else {
            CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
            org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();
            config = config.serializeValuesWith(SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader)));
            if (redisProperties.getTimeToLive() != null) {
                config = config.entryTtl(redisProperties.getTimeToLive());
            }

            if (redisProperties.getKeyPrefix() != null) {
                config = config.prefixKeysWith(redisProperties.getKeyPrefix());
            }

            if (!redisProperties.isCacheNullValues()) {
                config = config.disableCachingNullValues();
            }

            if (!redisProperties.isUseKeyPrefix()) {
                config = config.disableKeyPrefix();
            }

            return config;
        }
    }

自定义配置

容器中注入一个 RedisCacheConfiguration

java 复制代码
@EnableCaching
@Configuration
public class MyCacheConfig {
    @Autowired
    private CacheProperties cacheProperties;
    @Bean
    RedisCacheConfiguration redisCacheConfiguration(){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        //Json序列化
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
        //使配置文件生效
        CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }

        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }

        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }

        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }
        return config;
    }
}
R 复制代码
spring.cache.type=redis

#缓存空值,防止缓存穿透
spring.cache.redis.cache-null-values=true
#spring.cache.redis.time-to-live=3600000
#spring.cache.redis.key-prefix=CACHE_
spring.cache.redis.use-key-prefix=true

注解

@Cacheable

缓存方法返回值,若缓存命中则直接返回结果,否则执行方法并缓存结果。

键名 默认格式 缓存名::SimpleKeyparam1, param2,...,支持 SpEL 表达式

java 复制代码
@Cacheable(key = "#id")                 // 使用参数 id 作为键
@Cacheable(key = "#user.id")           // 使用对象属性作为键
@Cacheable(key = "#root.methodName")   // 使用方法名作为键[1,3](@ref)

默认使用jdk序列化机制,可在自定义配置中使用Json序列化器

@CacheEvict​​

清除缓存数据

sync = true

同步锁,本地锁,仅@Cacheable支持

java 复制代码
@Cacheable(cacheNames = "category",key = "#root.methodName",sync = true)
相关推荐
wangbing112525 分钟前
平台介绍-modbus设备调试
java
开开心心就好32 分钟前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
西索斯coding1 小时前
gpt-image-2.5-sunburst 和 gemini-3.1-flash-image 差多少?60 组项目素材的成功成本评测框架
java·linux·gpt·ai
wuminyu1 小时前
Java字节码学习总结:字节码如何加载、解析和执行
java·linux·c语言·jvm·c++
Flynn Liang2 小时前
大模型怎么自己调函数?Spring AI 2.0 Tool Calling 自动循环原理 + 完整时序图
java·人工智能·spring·agent·函数调用·springai·toolcalling
乌暮3 小时前
请求进门先安检:Spring 拦截器与统一功能实战指南
java·开发语言·后端·学习·spring
学长毕设3 小时前
基于SpringBoot的烘焙商品商品系统-附源码
java·spring boot·后端
howard20053 小时前
英中 / 中英对照制作程序:操作指南
spring boot·bootstrap·thymeleaf·操作指南·对照制作程序
金銀銅鐵4 小时前
[Java] 用纯 Swing 做一个《論語·學而》阅读器
java·ai编程·交互设计
艾伦_耶格宇4 小时前
【kubernetes - 1.28版本】-11 K8S核心组件
java·容器·kubernetes