【问题标题】:How can I make the cache name in Spring cache configurable?如何使 Spring 缓存中的缓存名称可配置?
【发布时间】:2012-10-22 19:00:59
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: java spring caching dependency-injection


    【解决方案1】:

    不,@Cacheable 注释的缓存名称 (value) 属性不支持动态(SpEL 或其他)表达式。您必须实现自己的 org.springframework.cache.annotation.SpringCacheAnnotationParser 版本并将其注入到框架中。

    【讨论】:

    • 谢谢,我在哪里可以找到一些关于如何实施 SpringCacheAnnotationParser 的文档或示例?
    • 我认为您将不得不深入研究实际代码并弄清楚。这并不是真正记录在案的“功能”,而是核心功能的修改/扩展。
    【解决方案2】:

    你也可以直接使用缓存,让一切更加可预测

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

    等等..

    【讨论】:

      【解决方案3】:

      Spring 4.1 引入CacheResolver,使用你自定义的CacheResolver 选择Cache 即可动态化。 spring 4.1 cache impovements

      【讨论】:

        【解决方案4】:

        离开smartwjw的回答...

        我希望通过 spring 环境变量解析 cacheNames,例如 @Cacheable("${my.config.property.name}")。我通过自定义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 一起使用。

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

        【讨论】:

          猜你喜欢
          • 2015-04-02
          • 1970-01-01
          • 2018-07-31
          • 2020-10-26
          • 2016-10-13
          • 2021-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多