`
234390216
  • 浏览: 10194092 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:460821
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1771877
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395481
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:393917
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678253
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529320
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178774
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:462010
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150169
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66890
社区版块
存档分类
最新评论

Ehcache(01)——简介、基本操作

阅读更多

Ehcache简介

目录

1       CacheManager

1.1      构造方法构建

1.2      静态方法构建

2       Cache

2.1      Cache的创建

 

       Ehcache是用来管理缓存的一个工具,其缓存的数据可以是存放在内存里面的,也可以是存放在硬盘上的。其核心是CacheManager,一切Ehcache的应用都是从CacheManager开始的。它是用来管理Cache(缓存)的,一个应用可以有多个CacheManager,而一个CacheManager下又可以有多个CacheCache内部保存的是一个个的Element,而一个Element中保存的是一个keyvalue的配对,相当于Map里面的一个Entry

 

1       CacheManager

       CacheManagerEhcache的核心,它的主要职责是对Cache的创建、移除和访问。只有CacheManager里面的Cache才能实现缓存数据的功能。一切使用Ehcache的应用都是从构建CacheManager开始的。构建CacheManager时,我们可以直接通过其构造方法来进行构建,也可以通过使用CacheManager提供的静态方法来进行构建。

 

1.1     构造方法构建

       使用构造方法构建CacheManager时每次都会产生一个新的CacheManager对象,并且会以该CacheManager对应的name作为key保存该CacheManager。当我们在构建CacheManager时如果已经存在name相同正在使用的CacheManager,则会抛出异常。此外,当多个CacheManager对应的storePath相同时,则它们存放在磁盘上包含缓存信息的文件将会相互覆盖。

 

1.使用默认配置

       当我们使用CacheManager的无参构造方法来构造CacheManager时就是使用的默认配置。这种情况最终还是会寻找默认的配置文件进行配置。Ehcache首先会到类根路径下寻找一个叫ehcache.xml的配置文件来配置CacheManager,如果没有找到该文件,则会加载CacheManager的默认配置ehcache-failsafe.xml文件,这个文件是在ehcache.jar里面的。关于配置文件如何配置的问题将在后续的文章中再做一个详细的讲解,这里先来简单看一个配置文件。

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
  
   <cache name="test" maxBytesLocalHeap="10M"/>
  
</ehcache>

 

       每一个配置文件的根元素都是ehcache,在该元素上可以指定一些CacheManager级别的参数。ehcache元素下的每一个cache元素代表一个缓存定义。cache元素上可以指定一些Cache级别的属性。下面是一个使用默认配置构建CacheManager的示例。

 
   @Test
   public void testDefault() {
      CacheManager cacheManager = new CacheManager();
      //输出当前cacheManager正在使用的配置对应的Xml格式文本
      System.out.println(cacheManager.getActiveConfigurationText());
   }

 

 

2.Configuration作为参数

       Configuration是用来指定CacheManager配置信息的,其它通过不同的方式所指定的构造参数最终都会转化为一个对应的Configuration对象,然后再利用该Configuration对象初始化CacheManager

   @Test
   public void test() {
      //新建一个CacheManager的配置信息
      Configuration configuration = new Configuration();
      //新建一个缓存的配置信息
      CacheConfiguration cacheConfiguration = new CacheConfiguration().name("test");
      //指定当前缓存的最大堆内存值为100M
      cacheConfiguration.maxBytesLocalHeap(100, MemoryUnit.MEGABYTES);
      //添加一个cache
      configuration.addCache(cacheConfiguration);
      configuration.dynamicConfig(false);  //不允许动态修改配置信息
      CacheManager cacheManager = new CacheManager(configuration);
      Cache cache = cacheManager.getCache("test");
      cache.put(new Element("test", "test"));
      System.out.println(cache.get("test").getObjectValue());;
   }

 

 

3.xml格式的配置对应的InputStream作为参数

       通过Xml格式的配置对应的InputStream作为参数时,Ehcache会对Xml进行解析,然后构造一个对应的Configuration对象。

   public void testInputStream() throws IOException {
      InputStream is = this.getClass().getClassLoader().getResourceAsStream("/ehcache.xml");
      CacheManager cacheManager = new CacheManager(is);
      is.close();
      System.out.println(cacheManager.getActiveConfigurationText());
   }

 

 

4.xml格式的配置文件对应的路径作为参数

   指定xml格式的配置文件对应的路径后,Ehcache会获取指定路径对应的配置文件,然后获取其输入流,再利用InputStream的方式构造CacheManager。这里的路径可以是相对路径,也可以是绝对路径。

   @Test
   public void testXmlPath() {
      //这个文件路径可以是相对路径,也可以是绝对路径。这里使用的是相对路径。
      CacheManager cacheManager = new CacheManager("src/main/resources/ehcache/ehcache.xml");
      System.out.println(cacheManager.getActiveConfigurationText());
   }

 

 

5.xml格式的配置对应的URL作为参数

       URL作为参数时,实际上ehcache还是通过获取URL对应的InputStream,然后再利用该InputStreamInputStream构造CacheManager的方式进行CacheManager的构造。

   @Test
   public void testURL() {
      URL url = this.getClass().getResource("/ehcache.xml");
      CacheManager cacheManager = new CacheManager(url);
      System.out.println(cacheManager.getActiveConfigurationText());
   }

 

 

1.2     静态方法构建

       CacheManager内部定义了一系列的用于构建CacheManager对象的静态方法。这主要可以分为两大类,一类是通过create()方法及其重载方法构建的,一类是通过newInstance()方法及其重载方法构建的。create()方法构建的都是单例,而newInstance()方法构建的可能是单例,也可能是多例。在CacheManager内部持有一个CacheManager类型的singleton对象,每次我们调用create()方法及其重载方法时,Ehcache都会判断当前的singleton对象是否非空,如果非空则直接返回,否则则以相应的配置构建一个CacheManager对象赋给singleton并进行返回。在调用newInstance()方法及其重载方法构建CacheManager时,Ehcache首先会判断我们之前是否创建过且还存在同样名称的CacheManager对象,如果有则直接返回该CacheManager对象,否则将新建一个CacheManager进行返回。所以调用CacheManagernewInstance()系列方法构建CacheManager与直接调用CacheManager的构造方法构造CacheManager对象的区别就在于调用newInstance()系列方法时如有同名的存在,会直接返回先前的,而不会抛出异常。此外CacheManager内部还定义了一个getInstance()静态方法,调用它时相当于是调用了不带参数的create()方法。

 

1.create()方法

       CacheManager内部一共定义有五个create()方法,分别对应于CacheManager的五个newInstance()方法,而每一个newInstance()方法又对应于CacheManager对应的构造方法。在调用时Ehcache会先判断CacheManager内部持有的singleton是否为空,非空则直接返回singleton,否则将返回对应参数的newInstance()返回的实例对象并赋值给singleton

   public void test() {
      //以默认配置创建一个CacheManager单例
      CacheManager cacheManager = CacheManager.create();
     
      //以config对应的配置创建CacheManager单例
      Configuration config = ...;//以某种方式获取的Configuration对象
      cacheManager = CacheManager.create(config);
     
      //以configurationFileName对应的xml文件定义的配置创建CacheManager单例
      String configurationFileName = ...;//xml配置文件对应的文件名称,包含路径
      cacheManager = CacheManager.create(configurationFileName);
     
      //以is对应的配置信息创建CacheManager单例
      InputStream is = ...; //以某种方式获取到的Xml配置信息对应的输入流
      cacheManager = CacheManager.create(is);
     
      //以URL对应的配置信息创建CacheManager单例
      URL url = ...;  //以某种方式获取到的Xml配置信息对应的URL
      cacheManager = CacheManager.create(url);
   }

 

 

2.newInstance()方法

       CacheManager内部一共定义有五个newInstance()方法,分别对应于CacheManager的五个构造方法。在调用newInstance()方法时,Ehcache会查看CacheManager内部是否保存有曾经新建的且同名的CacheManager,如果有则返回该对象,否则构建一个新的CacheManager对象进行返回。所以newInstance()方法并不一定会产生一个新的对象。

   public void test() {
      //以默认配置创建一个CacheManager
      CacheManager cacheManager = CacheManager.newInstance();
     
      //以config对应的配置创建CacheManager
      Configuration config = ...;//以某种方式获取的Configuration对象
      cacheManager = CacheManager.newInstance(config);
     
      //以configurationFileName对应的xml文件定义的配置创建CacheManager
      String configurationFileName = ...;//xml配置文件对应的文件名称,包含路径
      cacheManager = CacheManager.newInstance(configurationFileName);
     
      //以is对应的配置信息创建CacheManager
      InputStream is = ...; //以某种方式获取到的Xml配置信息对应的输入流
      cacheManager = CacheManager.newInstance(is);
     
      //以URL对应的配置信息创建CacheManager
      URL url = ...;  //以某种方式获取到的Xml配置信息对应的URL
      cacheManager = CacheManager.newInstance(url);
   }

 

 

1.3     CacheManager的关闭

       当我们不再需要使用CacheManager的时候,我们需要将CacheManager进行关闭。Ehcache为我们提供了一个关闭CacheManager的钩子,默认情况下是不可用的,通过设置系统属性net.sf.ehcache.enableShutdownHook=true就可以将该功能打开。但是官方还是推荐我们在程序里面调用CacheManagershutdown()方法来将当前CacheManager进行关闭。

 

2       Cache

       Ehcache中定义了一个对缓存进行处理的接口叫EhcacheCacheEhcache的一个实现类。Cache是由CacheManager进行管理的,使用CacheManager生成的就是一个Cache对象。Cache里面保存的是一个个的Element对象,这些对象通常都是保存在MemoryStore里面的,但也可以溢出到DiskStoreElement里面存放的是一个keyvalue的配对,其中keyvalue都是ObjectCache的创建可以事先在创建CacheManager的时候定义好,也可以在之后调用CacheManager实例的相关方法进行Cache的添加。Cache是线程安全的。

   @Test
   public void test() {
      CacheManager cacheManager = CacheManager.create();
      //以默认配置添加一个名叫cacheName的Cache。
      cacheManager.addCache("cacheName");
      Cache cache = cacheManager.getCache("cacheName");
      Element ele = new Element("key", "value");
      //把ele放入缓存cache中
      cache.put(ele);
   }

 

 

2.1     Cache的创建

       Cache的创建主要有两种方式,一种是通过Cache的构造方法创建,另一种是通过CacheManager创建。Cache中定义了一系列的构造方法,这里我们拿常用的利用CacheConfiguration来构造Cache做个示例。

   @Test
   public void cache() {
      //内存中保存的Element的最大数量
      int maxEntriesLocalHeap = 10000;
      CacheConfiguration cacheConfiguration = new CacheConfiguration("cacheName", maxEntriesLocalHeap);
      cacheConfiguration.overflowToOffHeap(false);
      Cache cache = new Cache(cacheConfiguration);
      //使用默认配置创建CacheManager
      CacheManager cacheManager = CacheManager.create();
      //只有添加到CacheManager中的Cache才是有用的
      cacheManager.addCache(cache);
      cache.put(new Element("key", "value"));
      System.out.println(cache.get("key"));
   }

 

 

       注意:通过使用Cache的构造方法直接new出来的Cache一定要添加到CacheManager中才能使用。

       通过CacheManager创建的Cache是指我们把Cache定义在CacheManager对应的配置信息里面,这样在创建CacheManager的时候也会把其中定义的Cache进行实例化并添加到对应的CacheManager中。根据构建CacheManager的方式不同,我们把Cache定义在CacheManager的配置信息中的方式也不同。总的来说有两种方式,一种是定义的对应的Xml格式的配置信息中,另一种是通过Configuration构建CacheManager时把CacheConfiguration添加到Configuration中。在之前介绍CacheManager的时候我们已经提到了在Ehcache配置文件中每一个cache元素代表一个Cache定义。简单示例如下:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
  
   <cache name="test" maxBytesLocalHeap="10M"/>
  
</ehcache>

 

 

       通过Configuration构建CacheManager时我们只需要把Cache定义即CacheConfiguration添加到Configuration中即可,示例代码如下:

   @Test
   public void cache2() {
      CacheConfiguration cacheConfiguration = new CacheConfiguration();
      cacheConfiguration.setName("test");  //指定cache名称
      cacheConfiguration.setMaxBytesLocalHeap("10M");   //指定最大可用堆内存
      Configuration config = new Configuration(); //构建一个空配置
      //添加Cache配置信息到CacheManager的配置信息中
      config.addCache(cacheConfiguration);
      CacheManager cacheManager = CacheManager.create(config);
      System.out.println(cacheManager.getOriginalConfigurationText());
      Cache cache = cacheManager.getCache("test");
      cache.put(new Element("key", "value"));
   }

 

 

 

2.2     Cache内容的CRUD

       Cache内容的CRUD是指对Cache中保存的元素进行CRUD操作。

1新增元素

       新增元素可以通过Cacheput(Element ele)方法来进行。Element是键值对形式,我们真正想要缓存的其实是Elementvalue,但是我们可以通过key来区别不同的value。同时Element中还包括我们缓存的一些额外信息,如缓存的时间等。Elementkeyvalue类似于Mapkeyvalue,均可为Object对象。

public class CacheCRUDTest {
  
   private CacheManager cacheManager;
  
   @Before
   public void before() {
      cacheManager = CacheManager.create();
      cacheManager.addCache("cache");
   }
  
   @After
   public void after() {
      cacheManager.shutdown();
   }
  
   /**
    * 往Cache中新增元素
    */
   @Test
   public void create() {
      Cache cache = cacheManager.getCache("cache");
      Element ele = new Element("key", "value");
      //把ele放入缓存cache中
      cache.put(ele);
   }
 
}

 

 

2获取元素

       获取元素的时候我们可以通过Cacheget()方法来进行的,其接收的参数是元素的key

   /**
    * 从Cache中读取元素
    */
   @Test
   public void read() {
      Cache cache = cacheManager.getCache("cache");
      //通过key来获取缓存中对应的元素
      Element ele = cache.get("key");
      System.out.println(ele);
      if (ele != null) {//当缓存的元素存在时获取缓存的值
         System.out.println(ele.getObjectValue());
      }
   }

 

 

3更新元素

       当我们在往Cache里面put元素的时候,如果Cache中已经存在相同key的元素了,则会用新的元素替换旧的元素,这也就意味着之前元素的一些信息将会丢失,如被查到的次数hitCount和创建时间等。

   /**
    * 更新元素
    */
   @Test
   public void update() {
      Cache cache = cacheManager.getCache("cache");
      cache.put(new Element("key", "value1"));
      System.out.println(cache.get("key"));
      //当添加元素的时候,如果缓存中已经存在相同key的元素则会将后者覆盖前者
      cache.put(new Element("key", "value2"));
      System.out.println(cache.get("key"));
   }

 

 

       此外,使用Cachereplace(Element ele)方法也可以更新Cache中对应的元素。与直接put更新不同的是,replace只会在Cache中拥有相同key的元素时才会对之前的元素进行更新。replace也会覆盖之前元素信息。

   /**
    * 更新元素
    */
   @Test
   public void update() {
      Cache cache = cacheManager.getCache("cache");
      cache.put(new Element("key", "value1"));
      System.out.println(cache.get("key"));
      //替换元素的时候只有Cache中已经存在对应key的元素时才会替换,否则不操作。
      cache.replace(new Element("key", "value2"));
      System.out.println(cache.get("key"));
   }

 

 

4删除元素

       删除元素是通过Cacheremove()方法进行的,其接收所要删除元素的key作为参数。

   /**
    * 根据key来移除一个元素
    */
   @Test
   public void delete() {
      Cache cache = cacheManager.getCache("cache");
      //根据key来移除一个元素
      cache.remove("key");
      System.out.println(cache.get("key"));
   }

 

 

 

(本文是基于Ehcache2.8.1写的)

13
1
分享到:
评论
9 楼 Hibernate1 2016-08-10  
文章写的很不错! 大体结构描述的很清晰
8 楼 smallbug_vip 2016-07-18  
very beautiful , thanks!!!
7 楼 wabiaozia 2016-06-06  
你这个系列教程讲的透彻
6 楼 u010574045 2016-05-18  
你好,运行:
    @Test 
    public void cache2() { 
       CacheConfiguration cacheConfiguration = new CacheConfiguration(); 
       cacheConfiguration.setName("test");  //指定cache名称 
       cacheConfiguration.setMaxElementsInMemory(1000); 
       Configuration config = new Configuration(); //构建一个空配置 
       //添加Cache配置信息到CacheManager的配置信息中 
       config.addCache(cacheConfiguration); 
       CacheManager cacheManager = CacheManager.create(config); 
       System.out.println(cacheManager.getOriginalConfigurationText()); 
       Cache cache = cacheManager.getCache("test"); 
       cache.put(new Element("key", "value")); 
    } 

总是报错

net.sf.ehcache.CacheException: Illegal configuration. No default cache is configured.
at net.sf.ehcache.config.ConfigurationHelper.createDefaultCache(ConfigurationHelper.java:215)
at net.sf.ehcache.CacheManager.configure(CacheManager.java:551)
at net.sf.ehcache.CacheManager.init(CacheManager.java:323)
at net.sf.ehcache.CacheManager.<init>(CacheManager.java:208)
at net.sf.ehcache.CacheManager.create(CacheManager.java:763)
at com.travelsky.pss.ehcache.test.EhcacheInstance.cache2(EhcacheInstance.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

5 楼 abcwt112 2015-10-28  
通俗易懂
4 楼 beijishiqidu 2015-08-04  
楼主为什么都不给一个对应的版本号呢?并且把代码中的important模块给出来也行啊,最起码让我们知道你引用的类是在那个包下么?这样的文章或许只有你自己能看懂吧。
3 楼 云端月影 2015-07-07  
     正在学习ehcache.
2 楼 beiyangshuishi 2015-01-17  
mark,正在学习ehcache.
原来项目用memcached当RBAC缓存,系统是分布式的但是。网络开销太大。想换换ehcache试试。
1 楼 zhuxinyu 2014-10-17  
mark一下,下一个月必定好好阅读ehcache

相关推荐

Global site tag (gtag.js) - Google Analytics