【问题标题】:SelfPopulatingCache incumbent cache issue (Spring 4, EhCache 2.10.3)SelfPopulatingCache 现有缓存问题(Spring 4,EhCache 2.10.3)
【发布时间】:2017-09-19 04:41:21
【问题描述】:

我有一个项目设置(这里的 sn-ps 来自我在 GitHub https://github.com/ashishmarwal/self-populating-cache-issue 上创建的一个演示项目) 在 ehcache 配置(ehcache .xml)。

<cache name="alphabet-description-cache"
       eternal="false"
       maxElementsInMemory="1000"
       memoryStoreEvictionPolicy="LRU"
       overflowToDisk="false"
       timeToLiveSeconds="300"
       timeToIdleSeconds="300" />

Spring bean 描述符然后使用原始缓存创建一个使用 CacheEntryFactory 的修饰 (SelfPopulatingCache):

<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="cacheManager"/>
</bean>

<!--Creating a decorated cache instance using the raw cache cinfigured in ehcache.xml -->
<bean id="alphabetDescriptionCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    <property name="cacheManager" ref="cacheManager"/>
    <property name="cacheName" value="alphabet-description-cache"/>
    <property name="cacheEntryFactory" ref="alphabetDescriptionCacheEntryFactory"/>
</bean>

<bean id="alphabetDescriptionCacheEntryFactory" class="com.marwals.ashish.issues.selfpopulatingcache.AlphabetDescriptionCacheEntryFactory" />

我们还有一个 test-context.xml 用于单元测试并声明一个 cacheManager 以及修饰的缓存(在我看来,我给这些缓存管理器起了不同的名字):

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="cacheManagerName" value="self-populating-cache-issue-demo-test"/>
    <property name="shared" value="true"/>
    <property name="acceptExisting" value="false"/>
    <property name="configLocation" value="classpath:/ehcache.xml"/>
</bean>

<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="cacheManager"/>
</bean>

<bean id="alphabetDescriptionCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    <property name="cacheManager" ref="cacheManager"/>
    <property name="cacheName" value="alphabet-description-cache"/>
    <property name="cacheEntryFactory" ref="alphabetDescriptionCacheEntryFactory"/>
</bean>

<bean id="alphabetDescriptionCacheEntryFactory" class="com.marwals.ashish.issues.selfpopulatingcache.AlphabetDescriptionCacheEntryFactory" />

这里的问题是,如果我有两个不同的测试,每个测试都加载主或测试上下文 bean 描述符,我会遇到一个现有的缓存问题:

    Error creating bean with name 'alphabetDescriptionCache' defined in class path resource [test-context.xml]: Invocation of init method failed; 
nested exception is net.sf.ehcache.CacheException: Cannot replace alphabet-description-cache It does not equal the incumbent cache.

有什么想法可以在这里出错吗?调试代码显示我有两个不同的缓存实例用于同一个原始缓存,然后 EhCache 的缓存管理器将其作为错误引发。

我创建了一个 git repo 来演示这个问题: https://github.com/ashishmarwal/self-populating-cache-issue

谢谢!!!

【问题讨论】:

    标签: java spring caching ehcache


    【解决方案1】:

    您在 Spring 配置中明确请求共享缓存管理器

    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="cacheManagerName" value="self-populating-cache-issue-demo"/>
        <property name="shared" value="true"/> <!-- here -->
        <property name="acceptExisting" value="false"/>
        <property name="configLocation" value="classpath:/ehcache.xml"/>
    </bean>
    

    这意味着对于给定的配置,Ehcache 将始终返回相同的CacheManager。在您的情况下(通常情况下)您不希望这样。

    只需将shared 设置为false 即可解决您的问题。

    【讨论】:

    • 谢谢@Henri。我会试试这个。我的真实场景有一堆带有测试弹簧上下文的测试,而一些带有真实弹簧上下文的测试。因此,在与这里的几个人讨论之后,我意识到使用真正的 spring 上下文的那些应该被声明为集成测试,并与用于运行单元测试的 surefire 分叉的 VM 分开运行。
    • 通常你不需要共享缓存管理器,因为你将拥有一个共享的 spring 应用程序上下文。这将传递地提供一个共享缓存管理器。因此,无论您采用哪种方式,缓存管理器都应该是共享的。
    猜你喜欢
    • 1970-01-01
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-23
    相关资源
    最近更新 更多