如何通过Springboot和@Cacheable注解完成方法调用拉去缓存以及@CacheEvict清空缓存的原理是怎样的

发布时间:2021-09-29 16:20:34 作者:柒染
来源:亿速云 阅读:208
# 如何通过Spring Boot和@Cacheable注解完成方法调用拉取缓存以及@CacheEvict清空缓存的原理是怎样的

## 目录
1. [引言](#引言)  
2. [Spring缓存抽象概述](#spring缓存抽象概述)  
3. [Spring Boot缓存自动配置](#spring-boot缓存自动配置)  
4. [@Cacheable注解深度解析](#cacheable注解深度解析)  
   - 4.1 [基本用法与参数详解](#基本用法与参数详解)  
   - 4.2 [缓存Key生成策略](#缓存key生成策略)  
   - 4.3 [条件缓存与unless条件](#条件缓存与unless条件)  
   - 4.4 [缓存同步模式](#缓存同步模式)  
5. [@CacheEvict注解原理剖析](#cacheevict注解原理剖析)  
   - 5.1 [缓存清除触发机制](#缓存清除触发机制)  
   - 5.2 [allEntries与beforeInvocation参数](#allentries与beforeinvocation参数)  
6. [缓存管理器实现原理](#缓存管理器实现原理)  
   - 6.1 [ConcurrentMapCacheManager](#concurrentmapcachemanager)  
   - 6.2 [RedisCacheManager](#rediscachemanager)  
7. [缓存代理机制实现](#缓存代理机制实现)  
   - 7.1 [AOP动态代理过程](#aop动态代理过程)  
   - 7.2 [缓存拦截器链](#缓存拦截器链)  
8. [实战:集成Redis缓存](#实战集成redis缓存)  
9. [性能优化与陷阱规避](#性能优化与陷阱规避)  
10. [总结与最佳实践](#总结与最佳实践)  

---

## 引言
在现代分布式系统架构中,缓存技术作为提升性能的核心手段,可有效降低数据库负载并加速数据访问。Spring Framework通过统一的缓存抽象层,配合Spring Boot的自动配置能力,使开发者能够以声明式的方式轻松集成缓存功能。本文将深入剖析`@Cacheable`和`@CacheEvict`两大核心注解的工作原理及其实现机制。

---

## Spring缓存抽象概述
Spring从3.1版本开始引入缓存抽象,主要包含以下核心接口:
```java
public interface Cache {
    String getName();
    Object get(Object key);
    void put(Object key, Object value);
    void evict(Object key);
    void clear();
}

public interface CacheManager {
    Cache getCache(String name);
    Collection<String> getCacheNames();
}

设计优势: - 解耦业务代码与具体缓存实现 - 支持多种缓存提供商(EhCache、Redis、Caffeine等) - 基于注解的声明式缓存操作


Spring Boot缓存自动配置

Spring Boot通过spring-boot-autoconfigure模块实现缓存自动配置,关键流程如下:

  1. 条件检测:检查类路径下是否存在CacheManager实现
  2. 默认配置:若无特定实现,则使用ConcurrentMapCacheManager
  3. 定制配置:通过application.properties调整参数
spring.cache.type=redis
spring.cache.redis.time-to-live=3600000

自动配置类

@Configuration
@ConditionalOnClass(CacheManager.class)
@EnableConfigurationProperties(CacheProperties.class)
public class CacheAutoConfiguration {
    // 配置逻辑...
}

@Cacheable注解深度解析

基本用法与参数详解

@Cacheable(value="users", key="#id")
public User getUserById(Long id) {
    return userRepository.findById(id);
}
参数 说明
value/cacheNames 指定缓存名称
key SpEL表达式定义缓存键
condition 执行前判断条件
unless 执行后判断条件

缓存Key生成策略

默认使用SimpleKeyGenerator

public class SimpleKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object... params) {
        if (params.length == 0) {
            return SimpleKey.EMPTY;
        }
        // 处理逻辑...
    }
}

自定义KeyGenerator示例:

@Bean
public KeyGenerator customKeyGenerator() {
    return (target, method, params) -> {
        return method.getName() + Arrays.toString(params);
    };
}

@CacheEvict注解原理剖析

缓存清除触发机制

@CacheEvict(value="users", key="#user.id")
public void updateUser(User user) {
    userRepository.update(user);
}

清除过程: 1. 通过AOP拦截方法调用 2. 解析注解参数获取缓存名称和Key 3. 调用Cache.evict()执行删除

allEntries与beforeInvocation参数


缓存管理器实现原理

RedisCacheManager工作流程

public class RedisCacheManager implements CacheManager {
    private final RedisCacheWriter cacheWriter;
    
    protected RedisCache createRedisCache(String name, 
        @Nullable RedisCacheConfiguration cacheConfig) {
        // 创建RedisCache实例
    }
}

缓存序列化

RedisCacheConfiguration.defaultCacheConfig()
    .serializeValuesWith(
        SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(User.class))
    );

缓存代理机制实现

AOP动态代理过程

Spring通过CacheInterceptor实现缓存逻辑:

public class CacheInterceptor extends CacheAspectSupport 
    implements MethodInterceptor {
    
    public Object invoke(MethodInvocation invocation) {
        // 执行缓存逻辑
    }
}

拦截器链执行顺序: 1. 检查@Cacheable条件 2. 查询缓存数据 3. 方法调用(缓存未命中时) 4. 结果缓存处理


实战:集成Redis缓存

配置示例

@Configuration
@EnableCaching
public class RedisConfig {
    
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(10));
        
        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .build();
    }
}

性能优化与陷阱规避

常见问题解决方案

  1. 缓存穿透:使用空值缓存
@Cacheable(value="users", unless="#result == null")
  1. 缓存雪崩:设置差异化的TTL
  2. 缓存一致性:采用@CachePut保证更新

总结与最佳实践

  1. 根据业务场景选择合适的缓存策略
  2. 监控缓存命中率(通过CacheStatistics
  3. 定期清理无效缓存
  4. 分布式环境使用集中式缓存

本文完整代码示例可参考GitHub仓库:spring-cache-demo “`

(注:此处为精简版大纲,完整13550字文章需扩展每个章节的详细实现原理、源码分析、性能对比数据及完整案例代码)

推荐阅读:
  1. Android之计算缓存大小并且清空缓存
  2. SDWebimage清空缓存

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

spring boot @cacheable @cacheevict

上一篇:Ubuntu Server中iptables防火墙怎么用

下一篇:go版本有哪些变化

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》