ehcache 2.8.3入門例:hello world、springでの使用

18541 ワード

一、pom.xml依存項目
 
<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
		</dependency>
		<dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.8.3</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>
	</dependencies>

 
 
二、ehcache.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<!-- 
        :
a.maxElementInMemory               ,   1000 ,           
b.eternal                       (      ,    )    false
c.timeToIdleSeconds=120    120  ,             ,     
d.timeToLiveSeconds=120             ,           120  ,       (  	       timeToIdleSeconds   ),                       。
e.overflowToDisk="true"            maxElementInMemory       ,                 ,             。
f.Ehcache          Ellment          。          ,     diskExpiryThreadIntervalSeconds     ,        ,             CPU  。    120 。
-->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">


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

    <defaultCache maxEntriesLocalHeap="10000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
        maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap" />
    </defaultCache>

    <cache name="sampleCache1" maxEntriesLocalHeap="10000"
        maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="20"
        timeToIdleSeconds="300" timeToLiveSeconds="600"
        memoryStoreEvictionPolicy="LFU" transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>

    <cache name="sampleCache2" maxEntriesLocalHeap="1000" eternal="true"
        memoryStoreEvictionPolicy="FIFO" />

</ehcache>

 三、サンプルコード
package com.cn.fangxin.ehcache.test;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.junit.*;

public class TestEhcache {
	
	@Test
	public void testEhcachae() throws InterruptedException {
		CacheManager manager = CacheManager.create();

        //      cacheName
        String names[] = manager.getCacheNames();
        System.out.println("----all cache names----");
        for (int i = 0; i < names.length; i++) {
            System.out.println(names[i]);
        }

        System.out.println("----------------------");
        //     cache  
        Cache cache1 = manager.getCache(names[0]);

        //  cache1       
        cache1.put(new Element("key1", "values1"));
        Element element = cache1.get("key1");

        //     
        System.out.println("key1 \t= " + element.getObjectValue());

        //       cache(ehcache    defaultCache  ,"test"       )
        Cache cache2 = new Cache("test", 1, true, false, 2, 3);
        manager.addCache(cache2);

        cache2.put(new Element("jimmy", "       "));

        //    1.5 ,       
        Thread.sleep(1500);

        Element eleJimmy = cache2.get("jimmy");

        //1.5s < 2s     
        if (eleJimmy != null) {
            System.out.println("jimmy \t= " + eleJimmy.getObjectValue());
        }

        //   0.5s,    :1.5 + 0.5 >= min(2,3),  
        Thread.sleep(500);

        eleJimmy = cache2.get("jimmy");

        if (eleJimmy != null) {
            System.out.println("jimmy \t= " + eleJimmy.getObjectValue());
        }

        //            
        System.out.println("fake \t= " + cache2.get("fake"));

        manager.shutdown();
	}

}

 実行結果:
----all cache names----sampleCache2sampleCache1----------------------key1     = values1jimmy     = 菩提樹の下の楊過fake    = null
 
四、timeToLiveSeconds、timeToIdleSecondsについて
この2つのパラメータは、キャッシュ・アイテムの有効期限に直接影響します.ドキュメントの説明を見ると、ほとんど役に立たないので、net.sf.ehcache.Elementソースのクリップを直接見ます.
/**
     * The amount of time for the element to live, in seconds. 0 indicates unlimited.
     */
    private volatile int timeToLive = Integer.MIN_VALUE;

    /**
     * The amount of time for the element to idle, in seconds. 0 indicates unlimited.
     */
    private volatile int timeToIdle = Integer.MIN_VALUE;
    
    
    /**
     * Sets time to Live
     * <P/>
     * Value must be a positive integer, 0 means infinite time to live.
     * <P/>
     * If calling this method with 0 as the parameter, consider using {@link #setEternal(boolean)}
     * or make sure you also explicitly call {@link #setTimeToIdle(int)}.
     *
     * @param timeToLiveSeconds the number of seconds to live
     */
    public void setTimeToLive(final int timeToLiveSeconds) {
        if (timeToLiveSeconds < 0) {
            throw new IllegalArgumentException("timeToLive can't be negative");
        }
        this.cacheDefaultLifespan = false;
        this.timeToLive = timeToLiveSeconds;
    }

    /**
     * Sets time to idle
     * <P/>
     * Value must be a positive integer, 0 means infinite time to idle.
     * <P/>
     * If calling this method with 0 as the parameter, consider using {@link #setEternal(boolean)}
     * or make sure you also explicitly call {@link #setTimeToLive(int)}.
     *
     * @param timeToIdleSeconds the number of seconds to idle
     */
    public void setTimeToIdle(final int timeToIdleSeconds) {
        if (timeToIdleSeconds < 0) {
            throw new IllegalArgumentException("timeToIdle can't be negative");
        }
        this.cacheDefaultLifespan = false;
        this.timeToIdle = timeToIdleSeconds;
    }
    
    

    /**
     * An element is expired if the expiration time as given by {@link #getExpirationTime()} is in the past.
     *
     * @return true if the Element is expired, otherwise false. If no lifespan has been set for the Element it is
     *         considered not able to expire.
     * @see #getExpirationTime()
     */
    public boolean isExpired() {
        if (!isLifespanSet() || isEternal()) {
            return false;
        }

        long now = System.currentTimeMillis();
        long expirationTime = getExpirationTime();

        return now > expirationTime;
    }
    
    
    /**
     * An element is expired if the expiration time as given by {@link #getExpirationTime()} is in the past.
     * <p>
     * This method in addition propogates the default TTI/TTL values of the supplied cache into this element.
     *
     * @param config config to take default parameters from
     * @return true if the Element is expired, otherwise false. If no lifespan has been set for the Element it is
     *         considered not able to expire.
     * @see #getExpirationTime()
     */
    public boolean isExpired(CacheConfiguration config) {
        if (cacheDefaultLifespan) {
            if (config.isEternal()) {
                timeToIdle = 0;
                timeToLive = 0;
            } else {
                timeToIdle = TimeUtil.convertTimeToInt(config.getTimeToIdleSeconds());
                timeToLive = TimeUtil.convertTimeToInt(config.getTimeToLiveSeconds());
            }
        }
        return isExpired();
    }

    /**
     * Returns the expiration time based on time to live. If this element also has a time to idle setting, the expiry
     * time will vary depending on whether the element is accessed.
     *
     * @return the time to expiration
     */
    public long getExpirationTime() {
        if (!isLifespanSet() || isEternal()) {
            return Long.MAX_VALUE;
        }

        long expirationTime = 0;
        long ttlExpiry = creationTime + TimeUtil.toMillis(getTimeToLive());

        long mostRecentTime = Math.max(creationTime, lastAccessTime);
        long ttiExpiry = mostRecentTime + TimeUtil.toMillis(getTimeToIdle());

        if (getTimeToLive() != 0 && (getTimeToIdle() == 0 || lastAccessTime == 0)) {
            expirationTime = ttlExpiry;
        } else if (getTimeToLive() == 0) {
            expirationTime = ttiExpiry;
        } else {
            expirationTime = Math.min(ttlExpiry, ttiExpiry);
        }
        return expirationTime;
    }

    /**
     * @return true if the element is eternal
     */
    public boolean isEternal() {
        return (0 == timeToIdle) && (0 == timeToLive);
    }
    
    
    /**
     * Sets whether the element is eternal.
     *
     * @param eternal
     */
    public void setEternal(final boolean eternal) {
        if (eternal) {
            this.cacheDefaultLifespan = false;
            this.timeToIdle = 0;
            this.timeToLive = 0;
        } else if (isEternal()) {
            this.cacheDefaultLifespan = false;
            this.timeToIdle = Integer.MIN_VALUE;
            this.timeToLive = Integer.MIN_VALUE;
        }
    }

    /**
     * Whether any combination of eternal, TTL or TTI has been set.
     *
     * @return true if set.
     */
    public boolean isLifespanSet() {
        return this.timeToIdle != Integer.MIN_VALUE || this.timeToLive != Integer.MIN_VALUE;
    }

    /**
     * @return the time to live, in seconds
     */
    public int getTimeToLive() {
        if (Integer.MIN_VALUE == timeToLive) {
            return 0;
        } else {
            return timeToLive;
        }
    }

    /**
     * @return the time to idle, in seconds
     */
    public int getTimeToIdle() {
        if (Integer.MIN_VALUE == timeToIdle) {
            return 0;
        } else {
            return timeToIdle;
        }
    }
    
    
    /**
     * Set the default parameters of this element - those from its enclosing cache.
     * @param tti TTI in seconds
     * @param ttl TTL in seconds
     * @param eternal <code>true</code> if the element is eternal.
     */
    protected void setLifespanDefaults(int tti, int ttl, boolean eternal) {
        if (eternal) {
            this.timeToIdle = 0;
            this.timeToLive = 0;
        } else if (isEternal()) {
            this.timeToIdle = Integer.MIN_VALUE;
            this.timeToLive = Integer.MIN_VALUE;
        } else {
            timeToIdle = tti;
            timeToLive = ttl;
        }
    }

 
 
結論:
a) timeToIdleSeconds(アイドル時間)、timeToLiveSeconds(生存時間)がいずれも0に設定されている場合は、期限切れでないことを示します
b) timeToLiveSeconds設定>0の値のみの場合、Elementの有効期限はtimeToLiveSecondsです.
c) timeToIdleSeconds設定>0の値しかない場合、Elementの有効期限は(前回アクセス時間+timeToIdleSeconds)となり、より一般的に言えば、前回getが過ぎたので、今またgetしたいと思います.2回のgetの間隔>timeToIdleSecondsであれば、有効期限が切れます(つまり、最後のgetがnullになります)
d) timeToLiveSeconds,timeToIdleSecondsともに>0の値がある場合,最終失効時間はb),c)ルールを統合し,両者の最小値をとる
テスト1:
@Test
    public void testTimeToIdleSeconds() throws InterruptedException {
        CacheManager manager = CacheManager.create();

        Cache myCache = new Cache("MyCache", 1, true, false, 0, 0); // Cache        
        manager.addCache(myCache);

        String key = "A";

        System.out.println("-------------------------");
        Element elementPut = new Element(key, "Some Value", 2, 0); // timeToIdleSeconds 2 

        myCache.put(elementPut);//     
        System.out.println(myCache.get(key));//     

        Thread.sleep(1500);//  1.5 
        System.out.println(myCache.get(key));//     

        Thread.sleep(1500);//  1.5 
        System.out.println(myCache.get(key));//        3 ,        ,      " "2 ,    

        Thread.sleep(2500);//  2.5 
        System.out.println(myCache.get(key));//         2.5s,  >2s,  

    }

 
出力結果
[ key = A, value=Some Value, version=1, hitCount=1, CreationTime = 1407898361782, LastAccessTime = 1407898361787 ][ key = A, value=Some Value, version=1, hitCount=2, CreationTime = 1407898361782, LastAccessTime = 1407898363287 ][ key = A, value=Some Value, version=1, hitCount=3, CreationTime = 1407898361782, LastAccessTime = 1407898364787 ]null
 
テスト2:
@Test
    public void testTimeToLiveSeconds() throws InterruptedException {
        CacheManager manager = CacheManager.create();

        Cache myCache = new Cache("MyCache", 1, true, false, 0, 0); // Cache        
        manager.addCache(myCache);

        String key = "A";

        System.out.println("-------------------------");
        Element elementPut = new Element(key, "Some Value", 0, 2); // timeToLiveSeconds 2 

        myCache.put(elementPut);//     
        System.out.println(myCache.get(key));//     

        Thread.sleep(1500);//  1.5 
        System.out.println(myCache.get(key));//     (1.5s<2s, " " )

        Thread.sleep(1500);//  1.5 
        System.out.println(myCache.get(key));//      3s,>2s,   )

    }

 
出力結果
[ key = A, value=Some Value, version=1, hitCount=1, CreationTime = 1407898423291, LastAccessTime = 1407898423296 ][ key = A, value=Some Value, version=1, hitCount=2, CreationTime = 1407898423291, LastAccessTime = 1407898424797 ]null
 
テスト3:
@Test
    public void testTimeToIdleSecondsAndTimeToLiveSeconds()
            throws InterruptedException {
        CacheManager manager = CacheManager.create();

        Cache myCache = new Cache("MyCache", 1, true, false, 0, 0); // Cache        
        manager.addCache(myCache);

        String key = "A";

        System.out.println("-------------------------");
        Element elementPut = new Element(key, "Some Value", 2, 5); // timeToIdleSeconds 2 ,timeToLiveSeconds 3 

        myCache.put(elementPut);//     
        System.out.println(myCache.get(key));//     

        Thread.sleep(1600);//  1.6 
        System.out.println(myCache.get(key));//     (1.6s < min(2 ,5), " " )

        Thread.sleep(1600);//  1.6 
        System.out.println(myCache.get(key));//      3.2s,< min((1.6+2) ,5), " " )
        
        Thread.sleep(1600);//  1.6 
        System.out.println(myCache.get(key));//      4.8s,< min((3.2+2) ,5), " " )
        
        Thread.sleep(500);//  0.5 
        System.out.println(myCache.get(key));//      4.8+0.5=5.3s,> min((4.8+2) ,5),  )

    }

 
出力結果
[ key = A, value=Some Value, version=1, hitCount=1, CreationTime = 1407898480892, LastAccessTime = 1407898480897 ][ key = A, value=Some Value, version=1, hitCount=2, CreationTime = 1407898480892, LastAccessTime = 1407898482499 ][ key = A, value=Some Value, version=1, hitCount=3, CreationTime = 1407898480892, LastAccessTime = 1407898484099 ][ key = A, value=Some Value, version=1, hitCount=4, CreationTime = 1407898480892, LastAccessTime = 1407898485699 ]null
この2つのパラメータの設定については、以下のことをお勧めします.
a)キャッシュされたデータ自体に更新が存在しない場合(例えば、ほとんど動かない基礎データ)、timeToIdleSecondsのみを設定すると、このような利点は、バッファが常にアクセスされている場合、いつまでも期限切れにならないことであり、逆に、誰も使用していない場合、空き時間があると自動的に期限切れになり、リソースが解放されることである.
b)キャッシュされたデータ自体に定期的な更新の問題(例えば、天気予報など、数時間ごとにdbで更新されるデータ)がある場合は、2つのパラメータを同時に設定することができ、timeToLiveSecondsの値はdbの更新サイクルよりも小さくなければならない.このようにdbのデータが変化すると、しばらくするとキャッシュに更新される
 
四、springにehcacheを統合する
1、追加する依存
<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>3.0.5.RELEASE</version>
		</dependency>

 2、springでの構成
<bean id="ehcacheCacheManager"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation">
			<value>classpath:ehcache.xml</value>
		</property>
	</bean>

 
 
出典:http://yjmyzz.cnblogs.com