Я экспериментировал с функциями абстракции Spring 3.1 и заставлял их работать, но у нас есть некоторые пользовательские данные, которые я хотел бы кэшировать с использованием бранд-сессий.Spring 3.1 Session Scoped Beans for 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. Но каждый раз, когда я пытаюсь autowire моего объекта кэша я получаю следующее сообщение:
Ошибка создания боба с именем «scopedTarget.accountSettingsCache»: Scope «сессия» не активна для текущего потока; рассмотрите , определяющий прокси-объект с ограниченным доступом для этого компонента, если вы намереваетесь обратиться к нему из одноэлементного; nested exception is java.lang.IllegalStateException: Не найдено ни одного запроса, связанного с потоком: ссылаетесь ли вы на атрибуты запроса за пределы фактического веб-запроса или обрабатываете запрос за пределами изначально получающего потока? Если вы фактически работаете в пределах веб-запроса и все еще получаете это сообщение, возможно, ваш код работает за пределами DispatcherServlet/DispatcherPortlet: В этом случае использует RequestContextListener или RequestContextFilter для выставления текущего запроса .
У меня есть spring-aop-3.1.1.RELEASE.jar в моем классе. Я попытался написать обертку для ConcurrentMapCache, у которой есть конструктор по умолчанию без параметров, поэтому я могу установить для прокси-целевого класса значение true. Я попытался объявить их за пределами cacheManager и добавить их в список кешей позже.
Но каждый раз, когда я пытаюсь установить его как свойство или autowire его в классе (@Service или @Controller), он дает мне ту же ошибку. Как будто aop: scoped-proxy полностью игнорируется.
Я также пробовал ehCache, и это сработало, но похоже, что оно не поддерживает кеширование с сеансом. Я мог бы также попытаться написать собственный keyGenerator и использовать sessionId как часть ключа в кеше, но тогда мне придется управлять его жизненным циклом, у него может быть время истечения срока, но я хочу более тонкий контроль над данными в кеше , Любые идеи?
Спасибо.
Я не думаю, что вы должны использовать контекст сеанса бобы в кэше. Для работы с сессионным компонентом должно быть достаточно обычного компонента с ограниченным сеансом без кеша. Если вы хотите использовать кеш, то использование обычных боковых областей будет прекрасным, и вы будете использовать идентификатор сеанса где-нибудь в ключе кеша. –
Но почему он не позволяет мне авторизовать сеансовый компонент в класс @Service? –
это возможно, но другой вопрос выше. Это что-то еще? Если вы хотите «SimpleCacheManager» за сеанс, тогда создайте этот сеанс в боковом сеансе. В противном случае у вас есть фасоль с сессией, называемая 'shoppingCart', или что вам нужно, и подключите ее к контроллеру. Но я не понимаю, почему вам нужен слой кеширования только для бонусов, связанных с сеансом. –