2012-03-26 33 views
1

我一直在试验Spring 3.1 Cache抽象特性并让它们工作,但我们有一些用户特定的数据,我想用会话作用域bean来缓存。Spring 3.1会话作用域用于高速缓存

我的缓存-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> 

我有RequestContextListener和的ContextLoaderListener在web.xml中。 但每次我尝试我的自动装配缓存对象我得到以下信息:

错误创建名为“scopedTarget.accountSettingsCache”豆: 范围“会议”不是当前线程活跃;考虑 如果您打算从单例中引用它 ,则为此bean定义一个范围代理;嵌套异常是java.lang.IllegalStateException: 没有找到线程绑定的请求:您是否在实际的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作为缓存中的键的一部分,但之后我将不得不管理它的生命周期,它可能有一个到期时间,但我希望更好地控制缓存中的数据。 任何想法?

谢谢。

+1

我不认为你应该把你的缓存中的会话范围的Bean。只有没有缓存的正常会话范围的bean应该足够用于会话范围的bean。如果你想使用一个缓存,那么使用常规的scoped bean将会很好,你可以在缓存键的某个地方使用session-id。 – 2012-03-26 11:18:45

+0

但为什么它不会让我自动将会话范围的bean装入@Service类? – 2012-03-26 13:50:26

+0

这是可能的,但与上述问题不同。这是别的吗?如果你想在每个会话中使用一个'SimpleCacheManager',那么就使该bean的会话范围成为可能。否则,只需要一个名为'shoppingCart'的会话范围的bean或任何你需要的东西,然后将它连接到你的控制器。但是我不明白为什么你需要一个缓存层来处理会话范围的bean。 – 2012-03-26 14:06:44

回答

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> 
相关问题