【问题标题】:Failed to load ApplicationContext when using @Cacheable annotation使用@Cacheable注解时加载ApplicationContext失败
【发布时间】:2018-07-03 18:05:18
【问题描述】:

我正在将缓存集成到我的 Web 应用程序中,但由于某种原因,在添加 @Cacheable 注释时无法加载应用程序上下文。

我这两天一直在尝试解决这个问题,非常感谢您的帮助!

app.context.xml

<cache:annotation-driven cache-manager="EhCacheManagerBean" key-generator="customKeyGenerator" />

<bean id="EhCacheManagerBean" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheBean" />

<bean id="ehcacheBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:EhCache.xml" p:shared="true" />

<bean id ="customKeyGenerator" class="com.app.site.v2.cache.customKeyGenerator"/>

<bean id="siteService" class="com.app.site.v2.SiteService" primary="true"/>

EhCache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
     updateCheck="true"
     monitoring="autodetect"
     dynamicConfig="true">

<diskStore path="java.io.tmpdir" />

<cache name="cacheSite"
       maxEntriesLocalHeap="100"
       maxEntriesLocalDisk="1000"
       eternal="false"
       timeToIdleSeconds="300"
       timeToLiveSeconds="600"
       memoryStoreEvictionPolicy="LFU"
       transactionalMode="off">
    <persistence strategy="localTempSwap" />
</cache>

被缓存的方法

public class SiteService implements ISiteService {

    @Cacheable("cacheSite")
        public JsonObject getSiteJson(String siteId, boolean istTranslated) { ... }

}

正在抛出的异常

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'siteService' is expected to be of type 'com.app.site.v2.SiteService' but was actually of type 'com.sun.proxy.$Proxy57'

【问题讨论】:

  • 没有注释也能用吗? runtimeService bean 来自哪里?
  • @CrazySabbath 是的,如果我删除它有效的注释!,我更新了帖子!
  • 你有同名的具体类和接口SiteService - 哪个是com.app.site.v2.SiteService
  • @yegodm 我更新了帖子,抱歉造成误导!
  • 这意味着你在某个地方依赖于具体类com.app.site.v2.SiteService,而不是接口ISiteService。由于缓存可能使用代理,因此依赖关系失败。

标签: java spring caching javabeans ehcache


【解决方案1】:

@yegdom 的评论其实是正确答案。添加Cacheable 注解时,Spring 会生成一个实现ISiteService 的代理。在您的代码中的某处,您有一个需要 SiteService 的 bean,即实现。

共有三种解决方案(按优先顺序):

  • 删除无用的接口... 单个实现只是增加了复杂性,并没有直接的好处。删除它将强制 Spring 使用类代理
  • 修复你的依赖以使用ISiteService
  • proxy-target-class="true" 添加到cache:annotation-driven 以告诉Spring 创建一个类代理

我真的不推荐最后一个,因为您应该始终依赖接口或始终依赖类(并删除接口)。不能同时进行。

【讨论】:

  • 你救了我的命,谢谢伙计。
猜你喜欢
  • 2019-07-03
  • 2014-02-20
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
相关资源
最近更新 更多