Я экспериментировал с функциями абстракции 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 как часть ключа в кэше, но тогда мне пришлось бы управлять его жизненным циклом, у него мог бы быть срок действия, но я хочу более точный контроль над данными в кэше.
Есть идеи ?
Спасибо.