Ehcache jsr107: по умолчанию не применяется к программно созданным кешам - PullRequest
0 голосов
/ 12 октября 2018

Основываясь на моих выводах из моего предыдущего SO вопроса , я пытаюсь настроить JCaches в смешанной декларативной и императивной конфигурации, чтобы ограничить максимальный размер кэшей декларативным способом.

Я храню список кэшей и продолжительность (TTL) их записей в моем application.yaml, который я получаю с помощью загрузчика свойств.Затем я создаю свои кеши с помощью приведенного ниже кода:

@Bean
public List<javax.cache.Cache<Object, Object>> getCaches() {
    javax.cache.CacheManager cacheManager = this.getCacheManager();
    List<Cache<Object, Object>> caches = new ArrayList();
    Map<String, String> cacheconfigs = //I populate this with a list of cache names and durations;
    Set<String> keySet = cacheconfigs.keySet();
    Iterator i$ = keySet.iterator();

    while(i$.hasNext()) {
        String key = (String)i$.next();
        String durationMinutes = (String)cacheconfigs.get(key);
         caches.add((new GenericDefaultCacheConfigurator.GenericDefaultCacheConfig(key, new Duration(TimeUnit.MINUTES, Long.valueOf(durationMinutes)))).getCache(cacheManager));
    }

    return caches;
}

@Bean
public CacheManager getCacheManager() {
    return Caching.getCachingProvider().getCacheManager();
}

private class GenericDefaultCacheConfig {
    public GenericDefaultCacheConfig(String cacheName, Duration duration) {
        public GenericDefaultCacheConfig(String id, Duration duration, Factory expiryPolicyFactory) {
        CACHE_ID = id;
        DURATION = duration;
        EXPIRY_POLICY = expiryPolicyFactory;
    }
    private MutableConfiguration<Object, Object> getCacheConfiguration() {
        return new MutableConfiguration<Object, Object>()
                    .setTypes(Object.class, Object.class)
                    .setStoreByValue(true)
                    .setExpiryPolicyFactory(EXPIRY_POLICY);
    }
    public Cache<Object, Object> getCache(CacheManager cacheManager) {
        CacheManager cm = cacheManager;
        Cache<K, V> cache = cm.getCache(CACHE_ID, Object.class, Object.class);
        if (cache == null)
           cache = cm.createCache(CACHE_ID, getCacheConfiguration());
        return cache;
    }
}

Я пытаюсь ограничить размер кеша следующим файлом ehcache.xml:

<config
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns='http://www.ehcache.org/v3'
    xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
    xsi:schemaLocation="
    http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
    http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">

<service>
    <jsr107:defaults default-template="heap-cache" enable-management="true" enable-statistics="true">
    </jsr107:defaults>
</service>

<cache-template name="heap-cache">
    <resources>
        <heap unit="entries">20</heap>
    </resources>
</cache-template> </config>

Я установил следующую декларацию в своем приложении.yaml:

spring:
  cache:
    jcache:
      config: classpath:ehcache.xml

Однако мои кэши не соблюдают установленный лимит.Я проверяю с помощью следующего теста:

    @Test
public void testGetCacheMaxSize() { 
    Cache<Object, Object> cache = getCache(MY_CACHE); //I get a cache of type Eh107Cache[myCache]

    CacheRuntimeConfiguration<Object, Object> ehcacheConfig = (CacheRuntimeConfiguration<Object, Object>)cache.getConfiguration(
            Eh107Configuration.class).unwrap(CacheRuntimeConfiguration.class);
    long size = ehcacheConfig.getResourcePools().getPoolForResource(ResourceType.Core.HEAP).getSize(); //Returns 9223372036854775807 instead of the expected 20

    for(int i=0; i<30; i++)
        commonDataService.getAllStates("ENTRY_"+i);

    Map<Object, Object> cachedElements = cacheManagerService.getCachedElements(MY_CACHE);
    assertTrue(cachedElements.size().equals(20)); //size() returns 30
}

Может кто-нибудь указать, что я делаю неправильно?Заранее спасибо.

1 Ответ

0 голосов
/ 30 октября 2018

Проблема возникает из-за получения диспетчера кэша следующим образом:

Caching.getCachingProvider().getCacheManager();

Установив URI файла конфигурации при инициализации диспетчера кэша, я получил его на работу:

cachingProvider = Caching.getCachingProvider();
configFileURI = resourceLoader.getResource(configFilePath).getURI();
cacheManager = cachingProvider.getCacheManager(configFileURI, cachingProvider.getDefaultClassLoader());

Я был подожидание, что Spring Boot автоматически создаст менеджер кэша на основе файла конфигурации, включенного в свойство spring.cache.jcache.config , но это не так, потому что вместо этого я получаю менеджер кэша, как описано вышепросто автоматически подключить его и позволить Spring создать его.

...