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

发布于:2025-08-09 ⋅ 阅读:(14) ⋅ 点赞:(0)

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

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

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

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

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

    @Override
    public 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 {

    @Cacheable
    public User getUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }

    @Cacheable
    public 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)
    @Bean
    public CacheManager caffeineCacheManager() {
        CaffeineCacheManager manager = new CaffeineCacheManager();
        manager.setCaffeine(Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES));
        return manager;
    }

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


网站公告

今日签到

点亮在社区的每一天
去签到