ehcache3-spring

ehcache3和spring都支持jcache,二者必然可以很方便的整合在一起。

    <!--开启spring cache注解-->
    <cache:annotation-driven mode="proxy" cache-manager="cacheManager"/>
    <!--CacheManager-->
    <bean id="cacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
        <property name="cacheManager" ref="jCacheManagerFactory"/>
    </bean>
    <!--这里的JCacheManagerFactory就相当于CachingProvider,通过CachingProvider就可以得到CacheManager,-->
    <!--JCacheManagerFactoryBean是一个FactoryBean,通过getObject可以得到CacheManager实例-->
    <bean id="jCacheManagerFactory"
          class="org.springframework.cache.jcache.JCacheManagerFactoryBean">
        <!--这里只能配置一个ehcache文件-->
        <property name="cacheManagerUri" value="classpath:ehcache.xml" />
    </bean>

 下面的afterPropertiesSet是JCacheManagerFactoryBean的逻辑,JCacheManagerFactoryBean通过getObject方法将cacheManager注入JCacheCacheManager中。

 

但是这样整合是存在问题的,下面是org.springframework.cache.jcache.JCacheCacheManager的一段逻辑,当ehcache配置的cache声明了非Object的keyType、valueType这里就会出现问题。那是不是说将keyType、valueType均设置为Object,或不进行设置(默认为Object)就可以了呢?

的确可行,我们可以进行类似如下的配置,但如果我们需要一种灵活的serializer配置,比如我希望有若干个default serializer,这若干个default serializer是针对若干个特定class进行序列化的,这种配置虽然可以继续使用,但显然不太合适,我是反感这种“含糊”的配置的,我更喜欢“精确”的配置(即指定key-type、value-type)。

 1     <cache alias="off-heap-cache">
 2         <!--可以为key、value指定serializer,也可以在cacheManager级别指定Object的默认serializer-->
 3         <key-type serializer="com.zyong.spring.ehcache.BaseSerializer"/>
 4         <value-type serializer="com.zyong.spring.ehcache.BaseSerializer"/>
 5         <expiry>
 6             <tti unit="minutes">5</tti>
 7         </expiry>
 8         <resources>
 9             <heap>1</heap>
10             <offheap unit="MB">1</offheap>
11         </resources>
12     </cache>

 

那么,如何让配置变得“精确”,又能适配spring呢?这里,我对JCacheCacheManager做了一些扩展,在spring与ehcache整合的配置文件中,将原JCacheCacheManager替换为该JCacheEhCacheManager 即可,这样就可以在ehcache配置文件中指定key-type、value-type了。

 1 public class JCacheEhCacheManager extends org.springframework.cache.jcache.JCacheCacheManager {
 2     @Override
 3     protected Collection<Cache> loadCaches() {
 4         Collection<Cache> caches = new LinkedHashSet<Cache>();
 5         EhcacheManager ehcacheManager;
 6         try {
 7             ehcacheManager = getCacheManager().unwrap(EhcacheManager.class);
 8         } catch (Exception e) {
 9             //如果不是Ehcache,则使用原loadCaches
10             return super.loadCaches();
11         }
12         Set<Map.Entry<String, CacheConfiguration<?, ?>>> entries = ehcacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet();
13         for (Map.Entry<String, CacheConfiguration<?, ?>> entry : entries) {
14             //获取cache配置
15             CacheConfiguration<?, ?> cacheConfiguration = entry.getValue();
16             //通过cacheName、keyType、valueType获取cache
17             javax.cache.Cache jcache = getCacheManager().getCache(entry.getKey()
18                     , cacheConfiguration.getKeyType()
19                     , cacheConfiguration.getValueType());
20             caches.add(new JCacheCache(jcache, isAllowNullValues()));
21         }
22         return caches;
23     }
24 }

 

posted @ 2017-07-31 16:05  holoyong  阅读(1560)  评论(0编辑  收藏  举报