You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SpEL实现@CacheEvict动态配置多缓存名称?

场景设置

以下为配置内容:
application.properties

Property.cache = name1,name2,...,nameN

CacheManager.java

[...]
@Scheduler(time_of_schedule)
@CacheEvict(value="#{'${property.cache}.split()'}")
void dueCache(){
    log.info("cache clean");
}
[...]
问题描述

使用@CacheEvict的value属性时抛出异常:

nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'property.cache'.split(',')' in value "#{'${property.cache'.split(',')}"

核心问题:@CacheEvict的value类型为String[],直接用SpEL拆分配置字符串的写法无法适配该类型,同时存在配置键大小写不匹配的问题(配置为Property.cache,代码中写的是property.cache)。需找到通过SpEL从配置文件读取缓存名称列表并注入String[]类型value的可行方案。

已尝试方案
  • @CacheEvict(value = "#{'${property.cache}'.split(',')}", allEntries = true):仅在value为String类型时可行,适配String[]时出错
  • @CacheEvict(value = "#{T(java.util.Arrays).asList(#root.getProperty('property.cache').split(','))}", allEntries = true):同样仅适配String类型value
  • @CacheEvict(value = {"cache1","cache2"}, allEntries = true):手动枚举可正常运行,但扩展性差
  • @CacheEvict(value = "cache1", allEntries = true):单缓存名称可行,但无法批量处理
解决方案

方法1:类内注入数组后通过SpEL引用

先在类中用@Value将配置值注入为String[],再在@CacheEvict的SpEL中直接引用该数组:

@Component
public class CacheManager {

    // 注意配置键大小写与文件保持一致
    @Value("${Property.cache}")
    private String[] cacheNames;

    @Scheduler(time_of_schedule)
    @CacheEvict(value = "#{cacheNames}", allEntries = true)
    void dueCache() {
        log.info("cache clean");
    }
}

原理:SpEL可直接引用当前Bean的成员属性,cacheNames本身就是String[]类型,完美匹配@CacheEvict的value参数要求。

方法2:Spring Boot配置类绑定

适合Spring Boot项目,通过配置类统一管理缓存配置:

  1. 创建配置类绑定配置值:
@ConfigurationProperties(prefix = "property")
public class CacheProperties {
    private String[] cache;

    // getter、setter
    public String[] getCache() {
        return cache;
    }

    public void setCache(String[] cache) {
        this.cache = cache;
    }
}
  1. 在启动类或配置类上启用配置绑定:
@SpringBootApplication
@EnableConfigurationProperties(CacheProperties.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  1. 在缓存清理方法中通过SpEL引用配置类的属性:
@Component
public class CacheManager {

    private final CacheProperties cacheProperties;

    // 构造注入配置类
    public CacheManager(CacheProperties cacheProperties) {
        this.cacheProperties = cacheProperties;
    }

    @Scheduler(time_of_schedule)
    @CacheEvict(value = "#{cacheProperties.cache}", allEntries = true)
    void dueCache() {
        log.info("cache clean");
    }
}

优势:符合Spring Boot配置规范,便于扩展更多缓存相关配置。

方法3:修正SpEL写法直接转换数组

若不想额外注入属性,可修正SpEL的写法(注意配置键大小写一致):

@Scheduler(time_of_schedule)
@CacheEvict(value = "#{'${Property.cache}'.split(',')}", allEntries = true)
void dueCache() {
    log.info("cache clean");
}

注意:部分旧版本Spring可能存在SpEL返回数组无法直接适配@CacheEvict的String[]参数的问题,若出现此情况优先使用前两种方法。同时需确保配置文件中Property.cache的格式正确,无多余空格。

内容的提问来源于stack exchange,提问作者Massirito

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:55:29