ehcahe缓存实例

ehcahe的介绍

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。
Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。

主要的特性有

  1. 快速
  2. 简单
  3. 多种缓存策略
  4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
  5. 缓存数据会在虚拟机重启的过程中写入磁盘
  6. 可以通过RMI、可插入API等方式进行分布式缓存
  7. 具有缓存和缓存管理器的侦听接口
  8. 支持多缓存管理器实例,以及一个实例的多个缓存区域
  9. 提供Hibernate的缓存实现

ehcahe依赖的jar包

ehcache.jar
commons-logging-1.1.1.jar
backport-util-concurrent.jar

获取缓存对象

创建缓存管理器

从缓存管理器中获取缓存对象,进而操作缓存

// 1. 创建缓存管理器
CacheManager cacheManager = CacheManager.getInstance();
// 2. 获取缓存对象
cache = cacheManager.getCache("cacheName");

跟踪源码CacheManager.java

public static CacheManager getInstance() throws CacheException {
        return create();
}

public static CacheManager create() throws CacheException {
        // 单例模式
        synchronized(CacheManager.class) {
            if (singleton == null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Creating new CacheManager with default config");
                }
                // 初始化
                singleton = new CacheManager();
            } else if (LOG.isDebugEnabled()) {
                LOG.debug("Attempting to create an existing singleton. Existing singleton returned.");
            }

            return singleton;
        }
    }
    
public CacheManager() throws CacheException {
        this.status = Status.STATUS_UNINITIALISED;
        this.init((Configuration)null, (String)null, (URL)null, (InputStream)null);
}

默认这4个参数都为null

private void init(Configuration configuration, String configurationFileName, URL configurationURL, InputStream configurationInputStream) {
        Configuration localConfiguration = configuration;
        if (configuration == null) {
            localConfiguration = this.parseConfiguration(configurationFileName, configurationURL, configurationInputStream);
        } else {
            configuration.setSource("Programmatically configured.");
        }

        ConfigurationHelper configurationHelper = new ConfigurationHelper(this, localConfiguration);
        this.configure(configurationHelper);
        this.status = Status.STATUS_ALIVE;
        if (this.cacheManagerPeerProvider != null) {
            this.cacheManagerPeerProvider.init();
        }

        this.cacheManagerEventListenerRegistry.init();
        this.addShutdownHookIfRequired();
        this.addConfiguredCaches(configurationHelper);
 }

关注localConfiguration = this.parseConfiguration(configurationFileName, configurationURL, configurationInputStream);
进入该方法,会执行configuration = ConfigurationFactory.parseConfiguration();

public static Configuration parseConfiguration() throws CacheException {
        ClassLoader standardClassloader = ClassLoaderUtil.getStandardClassLoader();
        URL url = null;
        if (standardClassloader != null) {
            url = standardClassloader.getResource("/ehcache.xml");
        }

        if (url == null) {
            url = ConfigurationFactory.class.getResource("/ehcache.xml");
        }

        if (url != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Configuring ehcache from ehcache.xml found in the classpath: " + url);
            }
        } else {
            url = ConfigurationFactory.class.getResource("/ehcache-failsafe.xml");
            if (LOG.isWarnEnabled()) {
                LOG.warn("No configuration found. Configuring ehcache from ehcache-failsafe.xml  found in the classpath: " + url);
            }
        }

        return parseConfiguration(url);
    }

可以看到,回去根目录中寻找ehcache配置文件ehcache.xml,如果找不到会通过找到ehcache-failsafe.xml"(ehcache的jar包内置的文件)执行快速失败
No configuration found. Configuring ehcache from ehcache-failsafe.xml found in the classpath: jar:file:/D:/java-lib/ehcache.jar!/ehcache-failsafe.xml

此时缓存管理器中没有缓存对象,所以必须要配置ehcache.xml
在这里插入图片描述

配置文件ehcache.xml

<?xml version="1.0" encoding="GBK"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="ehcache.xsd">

	<cacheManagerPeerProviderFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
		properties="peerDiscovery=manual,
		rmiUrls=//127.0.0.1:40002/SimplePageCachingFilter" />

	<cacheManagerPeerListenerFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
		properties="hostName=127.0.0.1,port=40001, socketTimeoutMillis=12000" />

	<!-- 磁盘地址 C:\Users\YWX558~1\AppData\Local\Temp\-->
	<!-- System.getProperty("java.io.tmpdir") -->
	<diskStore path="java.io.tmpdir" />

	<!--         
		配置自定义缓存
		defaultCache:默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理
		maxElementsInMemory:缓存中允许创建的最大对象数
		maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大
		eternal:缓存中对象是否为永久的,如果是,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
		overflowToDisk:true表示当内存缓存的对象数目达到了
		maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。
		diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。
		diskPersistent:是否缓存虚拟机重启期数据,是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名 为cache名称,后缀名为index的文件,
						这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存,要想把 cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法。
		diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒
		timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是 0 就意味着元素可以停顿无穷长的时间。
		timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
		memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
	-->

	<defaultCache maxElementsInMemory="10000" eternal="false"
		overflowToDisk="true" timeToIdleSeconds="500" timeToLiveSeconds="1000"
		diskPersistent="false" diskExpiryThreadIntervalSeconds="120">
		<cacheEventListenerFactory
			class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
			properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />
	</defaultCache>

	<!-- 
		cache:为指定名称的对象进行缓存的特殊配置
		name:指定对象的完整名
		缓存的3 种清空策略
		1、FIFO ,first in first out (先进先出).
	     2、LFU , Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
	     3、LRU ,Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
	 -->
	<cache name="SimplePageCachingFilter" 
			maxElementsInMemory="10000"
			maxElementsOnDisk="10000" 
			eternal="false" 
			overflowToDisk="true"
			diskSpoolBufferSizeMB="20"
			diskPersistent="true" 
			diskExpiryThreadIntervalSeconds="120"
			timeToIdleSeconds="0" 
			timeToLiveSeconds="0" 
			memoryStoreEvictionPolicy="LFU">
		<cacheEventListenerFactory
			class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
	</cache>

</ehcache>

测试

public static void main(String[] args) {

//		ClassLoader standardClassloader = ClassLoaderUtil.getStandardClassLoader();
//        URL url = null;
//        if(standardClassloader != null)
//            url = standardClassloader.getResource("/ehcache.xml");
//        System.out.println("url==="+url);
//        System.out.println("url1==="+ConfigurationFactory.class.getResource("/ehcache.xml"));
//        System.out.println("url2==="+ClassLoader.getSystemResource("ehcache.xml"));
//        System.out.println("url3==="+ClassLoader.getSystemClassLoader().getResource("ehcache.xml"));
        
        // 1. 创建缓存管理器
        CacheManager cacheManager = CacheManager.getInstance();
        Cache cache = null;
        
        // 2. 获取缓存对象
        cache = cacheManager.getCache("SimplePageCachingFilter");
        System.out.println("cache="+cache);
        
        // 3. 创建元素
    	Element element = new Element("key1", "value1");
    	cache.put(element);
    	element = new Element("key2", "value2");
    	cache.put(element);

        // 5. 获取缓存
        Element value = cache.get("key1");
        System.out.println("key1="+value);
        System.out.println("key1的值="+value.getObjectValue());
        
        System.out.print("\n");
        System.out.println("开始循环所有key");
        cache.getKeys().forEach(System.out::println);

        // 6. 删除元素
        cache.remove("key1");
        
        // 7. 刷新缓存,存储到磁盘
        cache.flush();

        // 8. 关闭缓存管理器
        cacheManager.shutdown();
        
        System.out.println(System.getProperty("java.io.tmpdir"));
        
    }

控制台打印

cache=[ name = SimplePageCachingFilter status = STATUS_ALIVE eternal = false overflowToDisk = true maxElementsInMemory = 10000 maxElementsOnDisk = 10000 memoryStoreEvictionPolicy = LFU timeToLiveSeconds = 0 timeToIdleSeconds = 0 diskPersistent = true diskExpiryThreadIntervalSeconds = 120 cacheEventListeners: net.sf.ehcache.distribution.RMIAsynchronousCacheReplicator  hitCount = 0 memoryStoreHitCount = 0 diskStoreHitCount = 0 missCountNotFound = 0 missCountExpired = 0 ]
key1=[ key = key1, value=value1, version=1, hitCount=1, CreationTime = 1552361013985, LastAccessTime = 1552361013985 ]
key1的值=value1

开始循环所有key
key1
key2
C:\Users\YWX558~1\AppData\Local\Temp\
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值