Spring boot2.x和ehcache3.5是基于注释的错误

时间:2018-08-16 22:25:10

标签: spring-boot ehcache

//jsr107
  @Configuration
  @EnableCaching
  public class EhCacheConfig extends CachingConfigurerSupport {
    @Bean
    @Override
    public CacheManager cacheManager() {
        CacheConfiguration<String, String> cacheConfiguration = 
                CacheConfigurationBuilder
                .newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(10000L))
.withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofDays(2L)))
                    .withDispatcherConcurrency(4)
                .build();
        Map<String, org.ehcache.config.CacheConfiguration<?, ?>> cacheMap = new HashMap<>();
        cacheMap.put("vsk", cacheConfiguration);
        EhcacheCachingProvider ehcacheCachingProvider = (EhcacheCachingProvider) Caching.getCachingProvider();
         DefaultConfiguration defaultConfiguration = 
                 new DefaultConfiguration(cacheMap, ehcacheCachingProvider.getDefaultClassLoader());
         javax.cache.CacheManager cacheManager = 
                 ehcacheCachingProvider.getCacheManager(ehcacheCachingProvider.getDefaultURI(), defaultConfiguration);
//This is a mistake here.
        return new JCacheCacheManager(cacheManager);
    }
  //SimpleCacheResolver
    @Bean
    @Override
    public CacheResolver cacheResolver() {
        return new SimpleCacheResolver();
    }
  //SimpleKeyGenerator
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new SimpleKeyGenerator();
    }
  //SimpleCacheErrorHandler
    @Bean
    @Override
    public CacheErrorHandler errorHandler() {
        return new SimpleCacheErrorHandler();
    }
  }

下面是一条错误消息。:

       **Caused by: javax.cache.CacheException: Multiple CachingProviders have been configured when only a single CachingProvider is expected
        at javax.cache.Caching$CachingProviderRegistry.getCachingProvider(Caching.java:386)**
How do I deal with it?I have tried many changes or not.

3 个答案:

答案 0 :(得分:0)

该异常消息很明显,您具有多个缓存提供程序,因此,如果您想了解所有缓存提供程序,可以在spring-boot主函数中添加以下代码片段

public static void main(String[] args) {
        //list all the caching provider
        Iterator<CachingProvider> iterator = Caching.getCachingProviders(Caching.getDefaultClassLoader()).iterator();
        while(iterator.hasNext()) {
            CachingProvider provider = iterator.next();
            if (!(provider instanceof EhcacheCachingProvider)) {
                iterator.remove();
            }
        }

        SpringApplication.run(Run.class, args);
    }

答案 1 :(得分:0)

@clevertension的答案是正确的。您的类路径中有多个缓存提供程序。

但是,通常这是不正常的。因此,您应该清除类路径以删除所有不需要的内容。

然后,Caching正在注册所有提供程序。这是正常现象,因此删除其他对象并不是很漂亮。您可以使用EhcacheCachingProvider ehcacheCachingProvider = (EhcacheCachingProvider) Caching.getCachingProvider(EhcacheCachingProvider.class.getName());

检索所需的那个

最后,您可能不需要所有这些代码。以下代码应该做完全相同的事情,因为Spring会在启用缓存时寻找要使用的注册CacheManager

@Configuration
@EnableCaching
public class EhCacheConfig {

  @Bean
  public CacheManager cacheManager() {
    CacheConfiguration<String, String> cacheConfiguration =
        CacheConfigurationBuilder
            .newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(10000L))
            .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofDays(2L)))
            .withDispatcherConcurrency(4)
            .build();
    Map<String, CacheConfiguration<?, ?>> cacheMap = new HashMap<>();
    cacheMap.put("vsk", cacheConfiguration);
    EhcacheCachingProvider ehcacheCachingProvider = (EhcacheCachingProvider) Caching.getCachingProvider(EhcacheCachingProvider.class.getName());
    DefaultConfiguration defaultConfiguration =
        new DefaultConfiguration(cacheMap, ehcacheCachingProvider.getDefaultClassLoader());
    javax.cache.CacheManager cacheManager =
        ehcacheCachingProvider.getCacheManager(ehcacheCachingProvider.getDefaultURI(), defaultConfiguration);
    return new JCacheCacheManager(cacheManager);
  }

}

答案 2 :(得分:0)

只需通过设置设置来告诉spring使用哪个CachingProvider spring.cache.jcache.provider个属性,如

spring.cache.jcache.provider=org.ehcache.jsr107.EhcacheCachingProvider

我通过回顾JCacheCacheConfiguration的实现发现了这一点,Spring用于提供CacheManager Bean。它使用cacheProperties.getJcache().getProvider()来确定要使用哪个CacheProvider。如果未指定,则假定只有一个提供程序。

来自CacheProperties.JCache:

    /**
     * Fully qualified name of the CachingProvider implementation to use to retrieve
     * the JSR-107 compliant cache manager. Needed only if more than one JSR-107
     * implementation is available on the classpath.
     */
    private String provider;