Spring Cession Scoped Beans для кэша - PullRequest
1 голос
/ 26 марта 2012

Я экспериментировал с функциями абстракции Spring 3.1 Cache и заставил их работать, но у нас есть некоторые пользовательские данные, которые я хотел бы кэшировать с помощью 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>

У меня есть RequestContextListener и ContextLoaderListener в web.xml. Но каждый раз, когда я пытаюсь автоматически связать свой объект кеша, я получаю следующее сообщение:

Ошибка создания бина с именем 'scopedTarget.accountSettingsCache': Область 'сессия' не активна для текущего потока; рассматривать определение прокси области действия для этого компонента, если вы намереваетесь обратиться к нему из синглтона; Вложенное исключение - java.lang.IllegalStateException: Привязанный к потоку запрос не найден: Вы ссылаетесь на атрибуты запроса за пределами фактического веб-запроса или обработки запроса за пределами изначально получающий поток? Если вы на самом деле работаете в веб-запрос и до сих пор получают это сообщение, ваш код, вероятно, работает вне DispatcherServlet / DispatcherPortlet: в этом случае используйте RequestContextListener или RequestContextFilter, чтобы выставить текущий запрос.

У меня есть spring-aop-3.1.1.RELEASE.jar в моем classpath. Я попытался написать оболочку для ConcurrentMapCache, которая имеет конструктор по умолчанию без параметров, поэтому я могу установить для proxy-target-class значение true. Я попытался объявить их вне cacheManager и добавить их в список кэшей позже.

Но каждый раз, когда я пытаюсь установить его как свойство или автоматически связать его в классе (@Service или @Controller), он выдает мне ту же ошибку. Как будто aop: scoped-proxy полностью игнорируется.

Я также попробовал ehCache, и он работал, но, похоже, он не поддерживает кэширование в рамках сеанса. Я также мог бы попытаться написать собственный keyGenerator и использовать sessionId как часть ключа в кэше, но тогда мне пришлось бы управлять его жизненным циклом, у него мог бы быть срок действия, но я хочу более точный контроль над данными в кэше. Есть идеи ?

Спасибо.

1 Ответ

0 голосов
/ 19 декабря 2012

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...