2012-03-26 61 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> 
相關問題