对缓存的使用主要是领会它的原理,知道为什么要使用缓存,然后对实现进行了解,有4种缓存的实现,我这里说一下常用的Ehcache缓存;它的精髓就在于ehcache.xml的配置,具体实例和解义如下:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!--DiskStore 配置,cache文件的存放目录 ,主要的值有 *user.home - 用户主目录 * user.dir - 用户当前的工作目录 * java.io.tmpdir - Default temp file path默认的temp文件目录 --> <diskStore path="java.io.tmpdir"/> <!-- 指定CacheManagerEventListenerFactory,这个对象在缓存添加的时候会得到相应的通知 *class - CacheManagerEventListenerFactory的一个实现类 *properties - CacheManagerEventListenerFactory的属性值,以逗号(,)分割多个属性,如果没有实现类被指定,则系统不创建CacheManager的监听器,没有默认值 --> <cacheManagerEventListenerFactory class="" properties=""/> <!-- 在进行分布式缓存的应用时候需要指定CacheManagerPeerProviderFactory, 用来生成CacheManagerPeerProvider的实例,以便和集群中的其他CacheManager通信。 *class -CacheManagerPeerProviderFactory的一个实现类 *properties - CacheManagerPeerProviderFactory的属性值,以逗号(,)分割多个属性 Ehcache内建了2种基于RMI分布系统的通信策略(peerDiscovery): *automatic - 使用多播组。在一个节点加入或者推出集群的时候自动感应(或者说自动在局域网内部查找分布的peer) *manual - 硬编码方式,使用它的时候,需要手动指定节点的地址,rmiUrls="//server1/aaa|//server2/bbb"; --> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=automatic; multicastGroupAddress=230.0.0.1; multicastGroupPort=40001;" propertySeparator=","/> <cacheManagerPeerListenerFactory/> <!-- 必须属性: name:设置缓存的名称,用于标志缓存,惟一 maxElementsInMemory:在内存中最大的对象数量 maxElementsOnDisk:在DiskStore中的最大对象数量,如为0,则没有限制 eternal:设置元素是否永久的,如果为永久,则timeout忽略 overflowToDisk:是否当memory中的数量达到限制后,保存到Disk 可选的属性: timeToIdleSeconds:设置元素过期前的空闲时间 timeToLiveSeconds:设置元素过期前的活动时间 diskPersistent:是否disk store在虚拟机启动时持久化。默认为false diskExpiryThreadIntervalSeconds:运行disk终结线程的时间,默认为120秒 memoryStoreEvictionPolicy:当内存缓存达到最大,有新的element加入的时候,移除缓存中element的策略(以下三种) 1、 FIFO,first in first out,这个是大家最熟的,先进先出。 2、 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 3、 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 【注】:默认的Cache配置。用来实现CacheManager.add(String cacheName)创建的缓存 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <!-- [首先,你可以有多个cache] 可对缓存中的element配置诸如监听器和加载器。Ehcahe内建了一些: *cacheEventListenerFactory - 监听缓存中element的put, remove, update和expire事件 *bootstrapCacheLoaderFactory - 启动时加载缓存的element 每个用来做分布式缓存都必须设定element的事件监听器,用来在各个CacheManager节点复制消息。 Ehcache内建了基于RMI的实现 - RMICacheReplicatorFactory --> <cache name="personList" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="300" overflowToDisk="true" maxElementsOnDisk="1000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LFU"> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/> <!-- 也可以在这里自己写监听器(在缓存element的put,remove等操作时,做一些额外的操作) --> </cache> </ehcache>
然后对写一个类,生成CacheManager,很简单,不在赘述,看代码:
public class DwrEhcache { private static CacheManager cacheManger; public static synchronized CacheManager getInstace(){ if(cacheManger==null){ InputStream is = ClassLoader.getSystemResourceAsStream("ehcache.xml"); cacheManger = new CacheManager(is); } return cacheManger; } private static Cache getCache(String name){ Cache cache = DwrEhcache.getInstace().getCache(name); return cache; } public static void shutdown(){ if(cacheManger!=null){ cacheManger.shutdown(); } } public static Cache getPersonList(){ return DwrEhcache.getCache("personList"); } }
最后对上篇dwr博文进行一些小小的改动,就做到了使用缓存技术,当然不要使用RMI分布式缓存,那样没什么意思【在这里有点大材小用了】,呵呵;好了,看代码吧,简单的很:
public List<PersonBean> getAllPerson(){ ArrayList<PersonBean> persons = null; Cache cache = DwrEhcache.getPersonList(); ArrayList<PersonBean> list = new ArrayList<PersonBean>(); try { list = (ArrayList<PersonBean>)cache.get("personList").getObjectValue(); persons = (ArrayList<PersonBean>)list.clone(); } catch (Exception e) { list = null; } if(list == null){ persons= new ArrayList<PersonBean>(); PersonBean p1 = new PersonBean("Lucy",12,"女"); PersonBean p2 = new PersonBean("Jam",13,"男"); persons.add(p1);persons.add(p2); Element element = new Element("personList",persons); cache.put(element); System.out.println("手动添加的,不是从缓存中读取的...."); } return persons; }
一些OK,运行DWR项目,成功了、