zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    解析三种常见分布式锁的实现
    RabbitMQ基础概念详解
    数据库事务概念
    ECIF与CRM
    MQ(消息队列)学习
    数据粒度的设计
    链表之 头节点与尾指针 区别
    牛客之错题(2016.1.15) && 带头节点与不带头的区别
    数据结构之递归回溯算法
    LeetCode--Single Number
  • 原文地址:https://www.cnblogs.com/sonng/p/11348298.html
Copyright © 2011-2022 走看看