How can I make the cache name in Spring cache conf

2019-07-19 04:41发布

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.

4条回答
再贱就再见
2楼-- · 2019-07-19 05:04

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 ..

查看更多
不美不萌又怎样
3楼-- · 2019-07-19 05:05

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);
    }
}
查看更多
4楼-- · 2019-07-19 05:22

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

查看更多
孤傲高冷的网名
5楼-- · 2019-07-19 05:23

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.

查看更多
登录 后发表回答