简体   繁体   English

用于缓存的Spring 3.1会话范围Bean

[英]Spring 3.1 Session Scoped Beans for Cache

I have been experimenting with the Spring 3.1 Cache abstraction features and got them to work but we have some user specific data, which I would like to cache using session scoped beans. 我一直在尝试使用Spring 3.1 Cache抽象功能,并使它们起作用,但是我们有一些特定于用户的数据,我希望使用会话范围的bean进行缓存。

My cache-config.xml (imported into applicationContext.xml): 我的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>

I do have RequestContextListener and ContextLoaderListener in web.xml. 我在web.xml中确实有RequestContextListener和ContextLoaderListener。 But everytime I try to autowire my cache object I get the following message: 但是每次我尝试自动连接缓存对象时,都会收到以下消息:

Error creating bean with name 'scopedTarget.accountSettingsCache': Scope 'session' is not active for the current thread; 创建名称为“ scopedTarget.accountSettingsCache”的bean时出错:作用域“会话”在当前线程中未激活; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; 如果您打算从单例中引用它,请考虑为此bean定义作用域代理。 nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? 嵌套异常为java.lang.IllegalStateException:未找到线程绑定的请求:您是在实际Web请求之外引用请求属性,还是在原始接收线程之外处理请求? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. 如果您实际上是在Web请求中操作并且仍然收到此消息,则您的代码可能在DispatcherServlet / DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter公开当前请求。

I do have spring-aop-3.1.1.RELEASE.jar in my classpath. 我的类路径中确实有spring-aop-3.1.1.RELEASE.jar。 I tried writing a wrapper for ConcurrentMapCache that has a default constructor with no parameters so I can set proxy-target-class to true. 我尝试为ConcurrentMapCache编写包装,该包装具有没有参数的默认构造函数,因此可以将proxy-target-class设置为true。 I tried declaring them outside the cacheManager and adding it to the list of caches later. 我尝试在cacheManager外部声明它们,然后将其添加到缓存列表中。

But everytime I try to set it as a property or autowire it in a class (@Service or @Controller) it gives me the same error. 但是每次我尝试将其设置为属性或将其自动连接到类(@Service或@Controller)中时,都会出现相同的错误。 It's as if the aop:scoped-proxy is totally ignored. 好像aop:scoped-proxy被完全忽略了。

I also tried ehCache and it worked but it doesn't seem to support session scoped caching. 我也尝试了ehCache并成功了,但是它似乎不支持会话范围的缓存。 I could also try to write a custom keyGenerator and use the sessionId as part of the key in the cache, but then I would have to manage it's lifecycle, it could have an expiration time but I want finer control over the data in the cache. 我还可以尝试编写一个自定义keyGenerator并将sessionId用作缓存中密钥的一部分,但随后我必须管理它的生命周期,它可能有到期时间,但是我想更好地控制缓存中的数据。 Any ideas ? 有任何想法吗 ?

Thanks. 谢谢。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM