0079 Ehcache 3.x应用入门及通过JCache与Spring整合

基本要素:版本、概念与抽象

  • Ehcache 3.x是一个用Java语言实现的缓存库,并且实现了 JSR107规范
  • Ehcache从2.x升级到3.x后,Maven依赖从 net.sf.ehcache:ehcache:2.x 变成了org.ehcache:ehcache:3.x
  • Ehcache基本概念有:
    • 要缓存的对象是“键值对”
    • 键值对的容器就是“缓存Cache”
    • 每个缓存有自己的配置,就是“缓存配置CacheConfiguration”,通过CacheConfigurationBuilder构建
    • Ehcache中可以管理多个缓存,需要一个“缓存管理器CacheManager”。通过CacheManager+缓存的名称可以创建或获得缓存
    • 缓存对象的存储位置有: 堆内存heap;堆外内存offheap;硬盘disk。 offheap就是位于JVM外的内存,不受GC管理

通过编程方式创建缓存

引入依赖

        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.8.0</version>
        </dependency>

测试代码

    @Test
    public void testA() {
        CacheManagerBuilder builder = CacheManagerBuilder.newCacheManagerBuilder();
        CacheManager cacheManager = builder.build();
        cacheManager.init();//cacheManager创建后一定要初始化

        ResourcePoolsBuilder poolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder();
        ResourcePools pools = poolsBuilder.heap(10, EntryUnit.ENTRIES).build();//用于配置一个cache的heap/offheap/disk的容量.
        CacheConfigurationBuilder<Long, String> cacheConfigBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, pools);
        CacheConfiguration<Long, String> cacheConfiguration = cacheConfigBuilder.build();//创建一个缓存配置

        Cache myCache = cacheManager.createCache("myCache", cacheConfiguration);//根据缓存名称和缓存配置创建缓存
        myCache.put(1L, "hahaha");
        logger.info("{}", myCache.get(1L));
        cacheManager.close();//系统关闭时, 应调用cacheManager的close方法
    }

通过XML配置创建缓存

Ehcache的XML配置:

<?xml version="1.0" encoding="UTF-8" ?>
<config
        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xmlns='http://www.ehcache.org/v3'
        xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">

    <!-- 可以把多个缓存配置相同的部分抽象出来形成cache-template模板 -->
    <cache-template name="myDefaults">
        <key-type>java.lang.Long</key-type>
        <value-type>java.lang.String</value-type>
        <heap unit="entries">200</heap> 
    </cache-template>

    <cache alias="foo">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.String</value-type>
        <resources>
            <heap unit="entries">20</heap>   <!-- heap可以存储20个元素 -->
            <offheap unit="MB">10</offheap>  <!-- offheap可以存储10MB -->
        </resources>
    </cache>

    <!-- 继承cache-template模板 -->
    <cache alias="bar" uses-template="myDefaults">
        <key-type>java.lang.Number</key-type>
    </cache>

    <cache alias="simpleCache" uses-template="myDefaults" />

</config>

测试代码:

    @Test
    public void testB() {
        URL ehcacheConfigUrl = getClass().getResource("/ehcache.xml");
        Configuration configuration = new XmlConfiguration(ehcacheConfigUrl); //从XML配置改造缓存配置
        CacheManager cacheManager = CacheManagerBuilder.newCacheManager(configuration);//创建CacheManager
        cacheManager.init();

        Cache<String, String> foo = cacheManager.getCache("foo", String.class, String.class);//从CachaManager用缓存名称获取缓存
        foo.put("1", "hehehe");
        logger.info("{}", foo.get("1"));

        Cache<Number, String> bar = cacheManager.getCache("bar", Number.class, String.class);
        bar.put(1, "hohoho");
        logger.info("{}", bar.get(1));

        cacheManager.close();

    }

通过JSR107(JCache)的api获取Ehcache的缓存--编程方式

    @Test
    public void testA() {

        //CachingProvider provider = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
        CachingProvider provider = Caching.getCachingProvider();//通过spi技术找到provider. 适用于类路径中只有一个JCache实现, 否则得用上面一行代码指明provider
        CacheManager cacheManager = provider.getCacheManager();

        ResourcePoolsBuilder poolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder();
        ResourcePools pools = poolsBuilder.heap(10, EntryUnit.ENTRIES).build();
        CacheConfigurationBuilder<Long, String> configBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, pools);
        CacheConfiguration<Long, String> cacheConfig = configBuilder.build();//ehcache的configuration

        Cache<Long, String> cache = cacheManager.createCache("myCache", Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfig));//通过Eh107Configuration将ehcache的config转为jcache的config
        cache.put(1L, "hahaha");
        logger.info("{}", cache.get(1L));
        cacheManager.close();

    }

通过JSR107(JCache)的api获取Ehcache的缓存--XML配置

引入JSR107规范

        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>1.1.1</version>
        </dependency>

Ehcache的XML配置采用上面的
测试代码:

    @Test
    public void testB() throws Exception {

        CachingProvider provider = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
        URI uri = getClass().getResource("/ehcache.xml").toURI();
        CacheManager cacheManager = provider.getCacheManager(uri, getClass().getClassLoader());
        Cache<String, String> cache = cacheManager.getCache("foo", String.class, String.class);
        cache.put("1", "hehehe");
        logger.info("{}", cache.get("1"));
        cacheManager.close();

    }

通过JCache在Spring中注入Ehcache

Spring的XML配置

    <bean id="jCacheManager" class="org.springframework.cache.jcache.JCacheManagerFactoryBean">
        <property name="cacheManagerUri" value="classpath:ehcache.xml" />
    </bean>

    <bean id="cacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
        <property name="cacheManager" ref="jCacheManager" />
    </bean>

测试代码:

@ContextConfiguration("classpath:spring.xml")
public class SpringJcacheEhcacheTest extends AbstractTestNGSpringContextTests {

    private static final Logger logger = LoggerFactory.getLogger(SpringJcacheEhcacheTest.class);

    @Autowired
    private CacheManager cacheManager;

    @Test
    public void testA() {
        Cache<Number, String> barCache = cacheManager.getCache("bar", Number.class, String.class);
        barCache.put(1, "hahaha");
        barCache.put(2L, "hehehe");
        logger.info("{}", barCache.get(1));
        logger.info("{}", barCache.get(2L));
        cacheManager.close();
    }

}

其他--在Spring中注入Ehcache 2.x

引入Ehcache2.x

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.6</version>
        </dependency>

Ehcache 2.x配置

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false" monitoring="autodetect" dynamicConfig="true">

    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    />

    <cache name="foo"
           eternal="false"
           timeToLiveSeconds="300"
           maxElementsInMemory="2000"
           maxElementsOnDisk="20000"
           overflowToDisk="true"
           diskPersistent="true"
           memoryStoreEvictionPolicy="FIFO"/>

</ehcache>

spring的XML配置

    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache-2.x.xml"/>
    </bean>

    <bean id="cacheManager2.x" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="cacheManagerFactory"/>
    </bean>

测试代码:

@ContextConfiguration("classpath:spring.xml")
public class SpringEhcache2xTest extends AbstractTestNGSpringContextTests {

    private static final Logger logger = LoggerFactory.getLogger(SpringEhcache2xTest.class);

    @Autowired
    private EhCacheCacheManager ehCacheCacheManager;

    @Test
    public void testA() {
        CacheManager cacheManager = ehCacheCacheManager.getCacheManager();
        Cache cache = cacheManager.getCache("foo");
        Element ele = new Element(1L, "Ehcache 2.x");
        cache.put(ele);
        logger.info("{}", cache.get(1L).getObjectValue());
        cacheManager.shutdown();
    }

}

最后

Ehcache 3.x官方文档: http://www.ehcache.org/documentation/3.8/getting-started.html
完整代码: https://github.com/JamboSonng/Demo-Master/tree/master/Master-Ehcache

posted @ 2019-08-13 20:34  sonng  阅读(1701)  评论(1编辑  收藏  举报