我一直在试验Spring 3.1缓存抽象功能并让它们工作但我们有一些用户特定的数据,我想用会话范围的bean缓存它们。
我的cache-config.xml(导入到applicationContext.xml中):
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<!-- Activates various annotations to be detected in bean classes: Spring's @Required and @Autowired, as well as JSR 250's @Resource. -->
<context:annotation-config />
<context:component-scan base-package="my.package.whatevs" />
<!-- <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="false" mode="proxy" /> -->
<cache:annotation-driven cache-manager="cacheManager" />
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean id="defaultCache" class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="defaultCache" />
<bean id="accountSettingsCache" class="org.springframework.cache.concurrent.ConcurrentMapCache" scope="session">
<aop:scoped-proxy proxy-target-class="false" />
<constructor-arg>
<value>accountSettingsCache</value>
</constructor-arg>
</bean>
</set>
</property>
</bean>
</beans>
我在web.xml中有RequestContextListener和ContextLoaderListener。 但每次我尝试自动装配我的缓存对象时,我都会收到以下消息:
创建名为'scopedTarget.accountSettingsCache'的bean时出错: 范围'session'对于当前线程不活动;考虑 如果您打算引用它,则为该bean定义范围代理 来自单身人士;嵌套异常是java.lang.IllegalStateException: 找不到线程绑定请求:您指的是请求属性吗? 在实际的Web请求之外,或处理外部的请求 原来收到的帖子?如果你实际在里面经营 一个Web请求仍然收到此消息,您的代码可能是 在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下, 使用RequestContextListener或RequestContextFilter来公开 当前的要求。
我的classpath中有spring-aop-3.1.1.RELEASE.jar。 我尝试为ConcurrentMapCache编写一个包装器,它有一个没有参数的默认构造函数,所以我可以将proxy-target-class设置为true。 我尝试在cacheManager之外声明它们,然后将它添加到缓存列表中。
但每当我尝试将其设置为属性或在类(@Service或@Controller)中自动装配它时,它会给出同样的错误。 就像aop:scoped-proxy完全被忽略一样。
我也尝试过ehCache并且它有效,但它似乎不支持会话范围的缓存。 我也可以尝试编写一个自定义keyGenerator并使用sessionId作为缓存中密钥的一部分,但是我必须管理它的生命周期,它可能有一个到期时间,但我希望更好地控制缓存中的数据。 有任何想法吗 ?
感谢。
答案 0 :(得分:0)
<bean id="sessionLevelCacheManager" class="org.springframework.cache.support.SimpleCacheManager"
scope="session">
<property name="caches">
<set>
<bean id="sessionCache"
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
p:name="sessionCache">
</bean>
</set>
</property>
<aop:scoped-proxy proxy-target-class="false" />
</bean>
<bean id="compositeCacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<array>
<ref bean="applicationLevelCacheManager" />
<ref bean="sessionLevelCacheManager" />
</array>
</property>
<property name="fallbackToNoOpCache" value="true" />
</bean>