Статьи

Spring 3.1 Кеширование и Конфиг

Недавно я @Cacheable блог о Spring 3.1 и его новых аннотациях кэширования @Cacheable и @CacheEvict . Как и для всех функций Spring, вам необходимо выполнить определенную настройку, и, как обычно, это делается с помощью XML-файла конфигурации Spring. В случае кеширования включение @Cacheable и @CacheEvict не может быть проще, так как все, что вам нужно сделать, это добавить следующее в ваш конфигурационный файл Spring:

1
<cache:annotation-driven />

… Вместе с соответствующим определением схемы в объявлении вашего beans элемента XML:

… с характерными чертами:

…и:

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