首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring 4缓存密钥生成没有按预期工作。

Spring 4缓存密钥生成没有按预期工作。
EN

Stack Overflow用户
提问于 2014-07-07 14:52:14
回答 1查看 3.9K关注 0票数 1

在将spring升级到version 4之后,我们的自定义密钥生成器停止工作。在迁移之前,重写"generate“方法的代码被执行,但是在迁移到Spring4.0.5之后,代码根本不被执行。相反,我看到SimpleKeyGenerator总是被执行的。这是春天的虫子吗?为什么我不能像以前的版本那样用我自己的代码覆盖generate方法?

根上下文中的示例:

代码语言:javascript
复制
<cache:annotation-driven key-generator="cacheKeyGenerator" />
<bean id="cacheKeyGenerator" class="com.poalim.xp.general.cache.CacheKeyGenerator"/>

来自java密钥生成的示例(迁移之前)

代码语言:javascript
复制
public class CacheKeyGenerator extends DefaultKeyGenerator implements ApplicationContextAware {
public Object generate(Object target, Method method, Object... params) { 
    return  method.getName() + super.generate(target, method, params); 
}

}

迁移后的示例代码

代码语言:javascript
复制
public class CacheKeyGenerator extends SimpleKeyGenerator implements ApplicationContextAware {
public Object generate(Object target, Method method, Object... params) { 
    return  method.getName() + super.generate(target, method, params); 
}

}

附加信息:调试代码之后,我看到每次调用"generate“方法时,它只在SimpleKeyGenerator中执行,而不是在我的自定义CacheKeyGenerator类中执行。我试着理解为什么,所以我做了一些调试。在调试时,我看到有一个org.springframework.cache.interceptor.CacheAspectSupport类,它有一个私有属性:私有KeyGenerator keyGenerator =新的SimpleKeyGenerator();这个类在keyGenerator属性上有一个setter方法,并且我看到当上下文启动时,这个setter方法是用我的自定义CacheKeyGenerator调用的,所以我的结论是我的配置是正确的,并且在配置中没有问题。我还看到,当需要键加法时,keyGenerator属性“丢失”了"CacheKeyGenerator“值,并具有"SimpleKeyGenerator”。这解释了为什么我的自定义代码从未被执行,但我不明白为什么keyGenerator属性指向SimpleKeyGenerator。这似乎是一个SPring错误。有什么问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-07 15:43:11

在查看了您发送的示例代码之后,我发现您有两个问题:

@EnableCaching

当您使用Java时,@EnableCaching注释被设计为替代XML。例如:

代码语言:javascript
复制
 @Configuration
 @EnableCaching
 public class AppConfig implements CachingConfigurer {

     @Bean
     @Override
     public CacheManager cacheManager() {
         // configure and return an implementation of Spring's CacheManager SPI
         SimpleCacheManager cacheManager = new SimpleCacheManager();
         cacheManager.addCaches(Arrays.asList(new ConcurrentMapCache("default")));
         return cacheManager;
     }

     @Bean
     @Override
     public KeyGenerator keyGenerator() {
         // configure and return an implementation of Spring's KeyGenerator SPI
         return new MyKeyGenerator();
     }

 }

由于您使用的是XML配置:

代码语言:javascript
复制
<cache:annotation-driven key-generator="cacheKeyGenerator" />

您的代码中不应该有@EnableCaching注释,因为它可以覆盖您的FacadeImpl(从FacadeImpl中删除它)。

组件扫描覆盖

您有一个root-context.xml和一个servlet-context.xml配置,但是这两种配置都在扫描相同的包。缓存配置是在root-context.xml中声明的,因此这个上下文中的bean已经应用了缓存,但是,bean在没有应用缓存的servlet-context.xml中被复制(因为它们再次被扫描)。

由于您似乎并不真正需要根/web分离,所以我建议只创建一个ApplicationContext。为此,请执行以下操作:

1)从web.xml中删除以下行

代码语言:javascript
复制
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:root-context.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

2)通过将以下内容添加到root-context.xml中,直接导入servlet-context.xml文件

代码语言:javascript
复制
<beans:import resource="classpath:root-context.xml"/>

Tip

最后一件看起来有点奇怪的事情是,您依赖于密钥的toString()方法。我很想直接使用SimpleKey类来满足您的需要:

代码语言:javascript
复制
public Object generate(Object target, Method method, Object... params) {
    return new SimpleKey(method.getName(), params);
}

如果您可以公开提供复制问题的示例代码,并将其作为堆栈溢出的链接使用,那么您也更有可能获得此类问题的帮助。GitHub是托管示例项目的好地方。另外,在您确定之前,请不要大喊它是BUG :)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24613528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档