@Cacheable
блог о Spring 3.1 и его новых аннотациях кэширования @Cacheable
и @CacheEvict . Как и для всех функций Spring, вам необходимо выполнить определенную настройку, и, как обычно, это делается с помощью XML-файла конфигурации Spring. В случае кеширования включение @Cacheable
и @CacheEvict
не может быть проще, так как все, что вам нужно сделать, это добавить следующее в ваш конфигурационный файл Spring:
1
|
< cache:annotation-driven /> |
… Вместе с соответствующим определением схемы в объявлении вашего beans
элемента XML:
01
02
03
04
05
06
07
08
09
10
11
|
xsi:schemaLocation='http://www.springframework.org/schema/beans |
… с характерными чертами:
1
|
xmlns:cache='http://www.springframework.org/schema/cache' |
…и:
Однако это еще не конец истории, поскольку вам также необходимо указать менеджер кэширования и реализацию кэширования. Хорошей новостью является то, что если вы знакомы с настройкой других компонентов Spring, таких как менеджер транзакций базы данных, то нет ничего удивительного в том, как это делается.
Кажется, что классом менеджера кэша является любой класс, реализующий интерфейс Spring org.springframework.cache.CacheManager
. Он отвечает за управление одной или несколькими реализациями кэша, когда экземпляры (ы) реализации кэша отвечают за фактическое кэширование ваших данных.
Пример XML ниже взят из примера кода, использованного в моих последних двух блогах.
01
02
03
04
05
06
07
08
09
10
11
12
|
< bean id = 'cacheManager' class = 'org.springframework.cache.support.SimpleCacheManager' > < property name = 'caches' > < set > < bean class = 'org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean' p:name = 'employee' /> <!-- TODO Add other cache instances in here --> </ set > </ property > </ bean > |
В приведенной выше конфигурации я использую SimpleCacheManager
Spring для управления экземпляром их ConcurrentMapCacheFactoryBean
с реализацией кэша с именем: employee
.
Важно отметить, что ваш менеджер кэша ДОЛЖЕН иметь идентификатор компонента cacheManager
. Если вы ошибетесь, вы получите следующее исключение:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cache.interceptor.CacheInterceptor#0' : Cannot resolve reference to bean 'cacheManager' while setting bean property 'cacheManager' ; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cacheManager' is defined at org.springframework.beans.factory.support.BeanDefinitionValueResolver. resolveReference(BeanDefinitionValueResolver.java: 328 ) at org.springframework.beans.factory.support.BeanDefinitionValueResolver. resolveValueIfNecessary(BeanDefinitionValueResolver.java: 106 ) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. applyPropertyValues(AbstractAutowireCapableBeanFactory.java: 1360 ) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. populateBean(AbstractAutowireCapableBeanFactory.java: 1118 ) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. doCreateBean(AbstractAutowireCapableBeanFactory.java: 517 ) : : trace details removed for clarity : at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner. runTests(RemoteTestRunner.java: 683 ) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner. run(RemoteTestRunner.java: 390 ) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner. main(RemoteTestRunner.java: 197 ) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cacheManager' is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory. getBeanDefinition(DefaultListableBeanFactory.java: 553 ) at org.springframework.beans.factory.support.AbstractBeanFactory. getMergedLocalBeanDefinition(AbstractBeanFactory.java: 1095 ) at org.springframework.beans.factory.support.AbstractBeanFactory. doGetBean(AbstractBeanFactory.java: 277 ) at org.springframework.beans.factory.support.AbstractBeanFactory. getBean(AbstractBeanFactory.java: 193 ) at org.springframework.beans.factory.support.BeanDefinitionValueResolver. resolveReference(BeanDefinitionValueResolver.java: 322 ) |
Как я уже сказал выше, в моей простой конфигурации весь процесс SimpleCacheManager
. Это, согласно документации, обычно «полезно для тестирования или простых объявлений кэширования». Хотя вы могли бы написать свою собственную реализацию CacheManager
, ребята из Spring предоставили другие менеджеры кеша для различных ситуаций
-
SimpleCacheManager
— см. Выше. -
NoOpCacheManager
— используется для тестирования, поскольку фактически ничего неNoOpCacheManager
, но будьте осторожны, поскольку тестирование кода без кеширования можетNoOpCacheManager
когда вы включите кеширование. -
CompositeCacheManager
— позволяет использовать несколько менеджеров кэша в одном приложении. -
EhCacheCacheManager
— менеджер кеша, который оборачивает экземплярehCache
. Смотрите http://ehcache.org
Выбор менеджера кэша для использования в любой конкретной среде кажется очень хорошим использованием для Spring Profile
s. Увидеть:?
И это почти завершает, хотя для полноты, ниже приведен полный файл конфигурации, используемый в моих предыдущих двух блогах:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<? xml version = '1.0' encoding = 'UTF-8' ?> xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd'> <!-- Switch on the Caching --> < cache:annotation-driven /> <!-- Do the component scan path --> < context:component-scan base-package = 'caching' /> <!-- simple cache manager --> < bean id = 'cacheManager' class = 'org.springframework.cache.support.SimpleCacheManager' > < property name = 'caches' > < set > < bean class = 'org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean' p:name = 'employee' /> <!-- TODO Add other cache instances in here --> </ set > </ property > </ bean > </ beans > |
Как лейтенант Коломбо любит говорить «И еще одна вещь, вы знаете, что беспокоит меня об этом деле…»; Ну, есть несколько вещей, которые беспокоят меня о кеш-менеджерах, например:
- Что означают «Ребята в Spring» под «Полезно для тестирования или простых объявлений кэширования», когда речь идет о SimpleCacheManager? Точно, когда вы должны использовать это в гневе, а не для тестирования?
- Было бы целесообразно написать собственную реализацию
CacheManager
или даже реализациюCache
? - Каковы преимущества использования
EhCacheCacheManager
? - Как часто вам действительно нужен
CompositeCacheManager
?
Все, что я могу изучать в будущем …
Приятного кодирования и не забудьте поделиться!
Ссылка: Spring 3.1 Кэширование и настройка от нашего партнера JCG Роджера Хьюза в блоге Captain Debug’s Blog .