当前位置: 首页 > news >正文

@CacheConfig​​当前类中所有缓存方法详解

@CacheConfig​​当前类中所有缓存方法详解

在 Spring Cache 抽象中,@CacheConfig 是一个​​类级别注解​​,用于为​​当前类中的所有缓存方法(如 @Cacheable@CachePut@CacheEvict)提供默认配置​​。其核心作用是​​避免在每个方法上重复声明相同的缓存参数​​,提升代码简洁性和可维护性。

​一、核心属性与应用场景​

@CacheConfig 支持以下核心属性,用于定义类级别缓存的默认行为:

属性类型是否必填说明
cacheNamesString[]缓存名称的默认值(逗号分隔)。若方法注解未显式指定 value/cacheNames,则使用此配置。
keyGeneratorString键生成器的 Bean 名称(默认使用 SimpleKeyGenerator)。
cacheManagerString缓存管理器的 Bean 名称(默认使用全局配置的 cacheManager)。
keyPrefixString缓存键的前缀(Spring 4.3+ 支持,优先级高于 keyGenerator 中的默认前缀逻辑)。
conditionString类级别缓存方法的全局条件(SpEL 表达式,仅当方法满足条件时生效)。
unlessString类级别缓存方法的全局排除条件(SpEL 表达式,满足条件时不缓存结果)。

​二、典型使用场景​

@CacheConfig 适用于​​同一类中多个缓存方法需要共享相同配置​​的场景,例如:

  • 同一类中所有缓存操作使用相同的缓存名称(如 userCache)。
  • 同一类中所有缓存方法使用自定义的键生成策略。
  • 同一类中所有缓存方法需要统一的缓存管理器(如切换不同缓存实现)。

​三、具体用法示例​

​示例 1:统一缓存名称​

假设一个 UserService 类中所有缓存方法都使用 userCache 作为缓存名称,可通过 @CacheConfig(cacheNames = "userCache") 统一声明,避免每个方法重复写 value = "userCache"

@Service
@CacheConfig(cacheNames = "userCache") // 类级别统一缓存名称
public class UserService {// 方法 1:使用类级别的 cacheNames(无需显式声明 value)@Cacheable(key = "#userId")public User getUserById(Long userId) {return userRepository.findById(userId).orElse(null);}// 方法 2:显式声明 cacheNames 会覆盖类级别配置(可选)@Cacheable(value = "profileCache", key = "#userId")public UserProfile getUserProfile(Long userId) {return profileRepository.findById(userId).orElse(null);}
}
​示例 2:自定义键生成器​

若需要为类中所有缓存方法使用自定义的键生成逻辑(如拼接多个参数),可通过 keyGenerator 指定自定义的键生成器 Bean。

​步骤 1:定义自定义键生成器​

@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {@Overridepublic Object generate(Object target, Method method, Object... params) {// 自定义键格式:类名::方法名::参数1::参数2...return String.format("%s::%s::%s", target.getClass().getSimpleName(), method.getName(), Arrays.toString(params));}
}

​步骤 2:在类上通过 @CacheConfig 引用​

@Service
@CacheConfig(cacheNames = "userCache",keyGenerator = "customKeyGenerator" // 使用自定义键生成器
)
public class UserService {@Cacheablepublic User getUserById(Long userId) {return userRepository.findById(userId).orElse(null);}@Cacheablepublic User updateUser(Long userId, User newUser) {return userRepository.save(newUser);}
}

此时,两个方法的缓存键会自动生成为:

  • getUserById::[123](假设 userId=123
  • updateUser::[123, User{id=123,...}]
​示例 3:统一缓存管理器​

若应用需要为不同缓存类型(如本地缓存和分布式缓存)配置不同的缓存管理器,可通过 cacheManager 指定类级别的缓存管理器。

​步骤 1:配置多个缓存管理器​

@Configuration
public class CacheConfig {// 本地缓存管理器(Caffeine)@Beanpublic CacheManager caffeineCacheManager() {CaffeineCacheManager manager = new CaffeineCacheManager();manager.setCaffeine(Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES));return manager;}// 分布式缓存管理器(Redis)@Beanpublic CacheManager redisCacheManager(RedisConnectionFactory factory) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1));return RedisCacheManager.builder(factory).cacheDefaults(config).build();}
}

​步骤 2:在类上指定缓存管理器​

@Service
@CacheConfig(cacheManager = "redisCacheManager") // 使用 Redis 缓存管理器
public class UserService {@Cacheable(key = "#userId")public User getUserById(Long userId) {return userRepository.findById(userId).orElse(null);}
}
​示例 4:全局条件与排除条件​

通过 conditionunless 可以为类中所有缓存方法设置全局生效条件。

@Service
@CacheConfig(cacheNames = "userCache",condition = "#userId != null", // 仅当 userId 非空时缓存unless = "#result == null"      // 结果为 null 时不缓存
)
public class UserService {@Cacheable(key = "#userId")public User getUserById(Long userId) {return userRepository.findById(userId).orElse(null);}
}

此时,若 userIdnull 或查询结果为 null,则不会触发缓存操作。

​四、注意事项​

  1. ​作用范围限制​
    @CacheConfig 仅对当前类中声明的缓存方法(@Cacheable@CachePut@CacheEvict)有效,对子类或兄弟类的方法无影响。

  2. ​方法级注解优先级更高​
    若方法级别的缓存注解(如 @Cacheable(value = "profileCache"))显式声明了某个属性(如 value),则​​方法级配置会覆盖类级别的默认配置​​。

  3. ​属性冲突处理​

    • cacheNames:方法级未声明时使用类级别;方法级声明时覆盖类级别。
    • keyGenerator/cacheManager:方法级未声明时使用类级别;方法级声明时覆盖类级别。
    • condition/unless:类级别条件与方法级别条件为​​逻辑与(AND)关系​​(即两者都满足时才生效)。
  4. ​适用 Spring 版本​
    @CacheConfig 自 Spring 3.2 引入,所有 Spring Boot 1.x 及以上版本均支持。

​五、总结​

@CacheConfig 是 Spring Cache 中用于​​类级别缓存配置复用​​的核心注解,通过它可以统一管理同一类中所有缓存方法的公共参数(如缓存名称、键生成策略、缓存管理器等),显著减少重复代码,提升可维护性。结合方法级注解的灵活性,能够高效应对不同业务场景的缓存需求。

http://www.xdnf.cn/news/1261585.html

相关文章:

  • Redis数据组织方式
  • electron 静默安装同时安装完成后自动启动(nsis)
  • 38-TS之类型保护
  • 3D TOF 视觉相机:工业视觉的破局者,重塑视觉感知的未来
  • ​​《深入浅出K-means算法:从原理到实战全解析》​预告(提纲)
  • 13. 搜索引擎-ElasticSearch
  • 学习Java的Day27
  • 初识排序(下)-- 讲解超详细
  • Effective C++ 条款30:透彻了解inlining的里里外外
  • MQTT与服务器通讯
  • 微软公布Windows 2030,要彻底淘汰鼠标、键盘
  • 控制建模matlab练习13:线性状态反馈控制器-②系统的能控性
  • conda或mamba install 相关软件报错
  • MySQL数据库操作练习
  • 电脑IP地址是“169.254.x.x”而无法上网的原因
  • Maven/Gradle常用命令
  • 如何将 Vue 前端、Hardhat 合约和 Node.js 后端集成到一个项目中
  • 协同进化:AIGC、Agent和MCP如何相互促进共同发展
  • WinForm 对话框的 Show 与 ShowDialog:阻塞与非阻塞的抉择
  • ICCV-2025 | 同济上海AILab跨越虚拟与现实的具身导航!VLN-PE:重审视觉语言导航中的具身差距
  • 在Java中,守护线程(Daemon Thread)和用户线程(User Thread)以及本地线程(Native Thread)的区别
  • Go语言实战案例:简易JSON数据返回
  • 微软Azure AI Foundry正式上线GPT-5系列模型
  • 5 种简单方法将 Safari 书签转移到新 iPhone
  • 代码随想录刷题Day26
  • Pytest项目_day10(接口的参数传递)
  • WORD接受修订,并修改修订后文字的颜色
  • Autosar AP功能组状态和模型进程是否预定义后不改变了?
  • Electron——窗口
  • 嵌入式硬件接口总结