使用@Cacheable 注释时无法加载 ApplicationContext
Failed to load ApplicationContext when using @Cacheable annotation
我正在将缓存集成到我的 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'
@yegdom 的评论实际上是正确的答案。添加 Cacheable
注释时,Spring 生成一个实现 ISiteService
的代理。在您的代码中的某处,您有一个需要 SiteService
实现的 bean。
一共有三种方案(按优先顺序排列):
- 删除无用的接口...单一的实现只会增加复杂性而没有直接的好处。删除它将强制 Spring 使用 class 代理
- 修复您的依赖关系以使用
ISiteService
- 将
proxy-target-class="true"
添加到cache:annotation-driven
告诉Spring创建一个class代理
我真的不推荐最后一个,因为你应该总是依赖于接口或者总是依赖于 class(并删除接口)。不能同时。
我正在将缓存集成到我的 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'
@yegdom 的评论实际上是正确的答案。添加 Cacheable
注释时,Spring 生成一个实现 ISiteService
的代理。在您的代码中的某处,您有一个需要 SiteService
实现的 bean。
一共有三种方案(按优先顺序排列):
- 删除无用的接口...单一的实现只会增加复杂性而没有直接的好处。删除它将强制 Spring 使用 class 代理
- 修复您的依赖关系以使用
ISiteService
- 将
proxy-target-class="true"
添加到cache:annotation-driven
告诉Spring创建一个class代理
我真的不推荐最后一个,因为你应该总是依赖于接口或者总是依赖于 class(并删除接口)。不能同时。