如何使Spring缓存中的缓存名称可配置?

问题描述:

我们使用Spring缓存框架进行缓存,并且我们希望能够支持多种缓存名称空间,例如"book"或"isbn",并且缓存名称空间是可配置的,而不是在类中进行硬编码,喜欢,而不是拥有

We use Spring cache framework for caching, and we'd like to able to support multiple namespaces for caches, such as "book", or "isbn", with the cache namespaces being configurable, rather than hardcoded in the class, like, instead of having

@Cacheable({ "book","isbn"})
public Book findBook(ISBN isbn) {...}

我们希望能够以某种方式从属性文件中注入缓存名称,以便可以动态设置缓存名称,例如:

we want to be able somehow inject the cache name from a properties file, so that the cache name can be dynamically set, like:

@Cacheable({ #cachename1, #cachename2})
public Book findBook(ISBN isbn) {...}

我在这里使用SpEL,但根本不知道这是否可行.

I'm using SpEL here, but don't know if this is doable at all.

关闭 smartwjw 的答案...

我一直希望通过Spring环境变量(例如@Cacheable("${my.config.property.name}"))来解析cacheName.我通过自定义CacheResolver

I was looking to have cacheNames resolved via spring environment variables, such as @Cacheable("${my.config.property.name}"). I accomplished this via a custom CacheResolver

import java.util.Collection;
import java.util.stream.Collectors;

import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
import org.springframework.cache.interceptor.SimpleCacheResolver;
import org.springframework.core.env.PropertyResolver;

public class PropertyResolvingCacheResolver
    extends SimpleCacheResolver {

    private final PropertyResolver propertyResolver;

    protected PropertyResolvingCacheResolver(CacheManager cacheManager, PropertyResolver propertyResolver) {
        super(cacheManager);
        this.propertyResolver = propertyResolver;
    }

    @Override
    protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
        Collection<String> unresolvedCacheNames = super.getCacheNames(context);
        return unresolvedCacheNames.stream()
            .map(unresolvedCacheName -> propertyResolver.resolveRequiredPlaceholders(unresolvedCacheName)).collect(Collectors.toList());
    }
}

然后,您当然必须将其配置为CacheResolver,以与扩展org.springframework.cache.annotation.CachingConfigurerSupport@Configuration一起使用.

And then of course you must configure it as THE CacheResolver to use with a @Configuration that extends org.springframework.cache.annotation.CachingConfigurerSupport.

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    public static final String PROPERTY_RESOLVING_CACHE_RESOLVER_BEAN_NAME = "propertyResolvingCacheResolver";

    @Autowired
    private CacheManager cacheManager;
    @Autowired
    private Environment springEnv;

    @Bean(PROPERTY_RESOLVING_CACHE_RESOLVER_BEAN_NAME)
    @Override
    public CacheResolver cacheResolver() {
        return new PropertyResolvingCacheResolver(cacheManager, springEnv);
    }
}