How can I make the cache name in Spring cache configurable?

≯℡__Kan透↙ 提交于 2019-12-23 18:42:56

问题


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) {...}

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


回答1:


Spring 4.1 introduces CacheResolver, and use your self defined CacheResolver to select Cache then can be dynamic. spring 4.1 cache impovements




回答2:


Going off smartwjw's answer...

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());
    }
}

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);
    }
}



回答3:


Nope, dynamic (SpEL or otherwise) expressions are not supported for the cache name (value) property of the @Cacheable annotation. You would have to implement your own version of the org.springframework.cache.annotation.SpringCacheAnnotationParser and get it injected into the framework.




回答4:


you can also use the cache directly, makes all even more predictable

EhCacheCacheManager cacheManager = (EhCacheCacheManager) CDBBeanFactory.instance().getBean("cacheManager");
CacheManager manager cacheManager.getCacheManager();
manager.getCache("cacheBin").get("key");
manager.getCache("cacheBin").put(new Element(key, obj));

etc ..



来源:https://stackoverflow.com/questions/13189814/how-can-i-make-the-cache-name-in-spring-cache-configurable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!