Spring 3.1 Session Scoped Beans for Cache



我一直在尝试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.IollegalStateException:找不到绑定到线程的请求:您指的是请求属性吗在实际web请求之外,或在最初的接收线程?如果您实际在一个web请求,但仍然收到此消息,您的代码可能是在DispatcherServlet/DispatcherPortlet之外运行:在这种情况下,使用RequestContextListener或RequestContextFilter公开当前请求。

我的类路径中确实有spring-op-3.1.1.RELEASE.jar。我尝试为ConcurrentMapCache编写一个包装器,它有一个不带参数的默认构造函数,这样我就可以将代理目标类设置为true。我尝试在cacheManager之外声明它们,然后将其添加到缓存列表中。

但每次我试图将它设置为属性或在类(@Service或@Controller)中自动连接它时,都会出现同样的错误。就好像aop:scoped代理被完全忽略了一样。

我也尝试过ehCache,它很有效,但似乎不支持会话范围的缓存。我也可以尝试编写一个自定义密钥生成器,并将sessionId作为缓存中密钥的一部分,但随后我必须管理它的生命周期,它可能有一个过期时间,但我希望对缓存中的数据进行更精细的控制。有什么想法吗?

谢谢。

<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>

最新更新