1. 程式人生 > >SpringBoot之——配置EHCache

SpringBoot之——配置EHCache

第一步:在classpath下引入配置檔案ehcache.xml

<?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">
    <!--
       diskStore:為快取路徑,ehcache分為記憶體和磁碟兩級,此屬性定義磁碟的快取位置。引數解釋如下:
       user.home – 使用者主目錄
       user.dir  – 使用者當前工作目錄
       java.io.tmpdir – 預設臨時檔案路徑
     -->
    <diskStore path="java.io.tmpdir/Tmp_EhCache" />
    <!--
       defaultCache:預設快取策略,當ehcache找不到定義的快取時,則使用這個快取策略。只能定義一個。
     -->
     <!--
       name:快取名稱。
       maxElementsInMemory:快取最大數目
       maxElementsOnDisk:硬碟最大快取個數。 
       eternal:物件是否永久有效,一但設定了,timeout將不起作用。 
       overflowToDisk:是否儲存到磁碟,當系統當機時
       timeToIdleSeconds:設定物件在失效前的允許閒置時間(單位:秒)。僅當eternal=false物件不是永久有效時使用,可選屬性,預設值是0,也就是可閒置時間無窮大。
       timeToLiveSeconds:設定物件在失效前允許存活時間(單位:秒)。最大時間介於建立時間和失效時間之間。僅當eternal=false物件不是永久有效時使用,預設是0.,也就是物件存活時間無窮大。
       diskPersistent:是否快取虛擬機器重啟期資料 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. 
       diskSpoolBufferSizeMB:這個引數設定DiskStore(磁碟快取)的快取區大小。預設是30MB。每個Cache都應該有自己的一個緩衝區。 
       diskExpiryThreadIntervalSeconds:磁碟失效執行緒執行時間間隔,預設是120秒。
       memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。預設策略是LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。 
       clearOnFlush:記憶體數量最大時是否清除。
       memoryStoreEvictionPolicy:可選策略有:LRU(最近最少使用,預設策略)、FIFO(先進先出)、LFU(最少訪問次數)。
       FIFO,first in first out,這個是大家最熟的,先進先出。
       LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點就是講一直以來最少被使用的。如上面所講,快取的元素有一個hit屬性,hit值最小的將會被清出快取。
       LRU,Least Recently Used,最近最少使用的,快取的元素有一個時間戳,當快取容量滿了,而又需要騰出地方來快取新的元素的時候,那麼現有快取元素中時間戳離當前時間最遠的元素將被清出快取。
    -->
    <defaultCache
       eternal="false"
       maxElementsInMemory="1000"
       overflowToDisk="false"
       diskPersistent="false"
       timeToIdleSeconds="0"
       timeToLiveSeconds="600"
       memoryStoreEvictionPolicy="LRU" />

    <cache
       name="demo"  
       eternal="false"
       maxElementsInMemory="100"
       overflowToDisk="false"
       diskPersistent="false"
       timeToIdleSeconds="0"
       maxEntriesLocalHeap="200" 
       timeToLiveSeconds="300"
       memoryStoreEvictionPolicy="LRU" />
       
</ehcache>

第二步springboot開啟對快取的支援,你需要在springboot啟動的main方法上配置@EnableCaching註解即可

第三步就是程式碼使用demo了.程式碼如下:

首先我們建一個實體類:

package com.lyz.springboot.thing;

/**
 * 測試例項的實體類
 * @author liuyazhuang
 *
 */
public class Thing {

	private Long id;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}
}
然後我們注入一個service,模擬資料crud
package com.lyz.springboot.thing;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.assertj.core.util.Lists;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 * 例項Service
 * @author liuyazhuang
 *
 */
@Service
public class CacheDemoServiceImpl {

	private static Map<Long, Thing> data = new HashMap<>();// 用與快取模擬資料

	/**
	 * 快取的key
	 */
	public static final String THING_ALL_KEY = "\"thing_all\"";
	/**
	 * value屬性表示使用哪個快取策略,快取策略在ehcache.xml
	 */
	public static final String DEMO_CACHE_NAME = "demo";

	@CacheEvict(value = DEMO_CACHE_NAME, key = THING_ALL_KEY)
	public void create(Thing thing) {
		thing.setId(thing.getId());
		data.put(thing.getId(), thing);
	}

	@Cacheable(value = DEMO_CACHE_NAME, key = "#thing.id")
	public Thing findById(Thing thing) {
		Long id = thing.getId();
		System.err.println("沒有走快取!" + id);
		return data.get(id);
	}

	@Cacheable(value = DEMO_CACHE_NAME, key = THING_ALL_KEY)
	public List<Thing> findAll() {
		return Lists.newArrayList(data.values());
	}

	@CachePut(value = DEMO_CACHE_NAME, key = "#thing.id")
	@CacheEvict(value = DEMO_CACHE_NAME, key = THING_ALL_KEY)
	public Thing update(Thing thing) {
		System.out.println(thing);
		data.put(thing.getId(), thing);
		return thing;
	}

	@CacheEvict(value = DEMO_CACHE_NAME)
	public void delete(Long id) {
		data.remove(id);
	}

}
最後我們建立一個控制層來訪問資料做測試:
package com.lyz.springboot.thing;

import java.util.List;

import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 測試例項的Controller
 * @author liuyazhuang
 *
 */
@Controller
public class ThingController {
	@Autowired
    private CacheDemoServiceImpl cacheDemoServiceImpl;
    
    @RequestMapping("/test/add")
    public void test(@NotNull Long id) {
        Thing t=new Thing();
        t.setId(id);
        cacheDemoServiceImpl.create(t);
    
    }
    
    @RequestMapping("/test/list")
    @ResponseBody
    public List<Thing> testlist() {
        List<Thing> list=cacheDemoServiceImpl.findAll();
        return list;
    }
    
    @RequestMapping("/test/one")
    @ResponseBody
    public Thing testfind(@NotNull Long id) {
        Thing t=new Thing();
        t.setId(id);
        Thing tt=cacheDemoServiceImpl.findById(t);
        return tt;
    
    }
    
    @RequestMapping("/test/delete")
    public void testdelete(@NotNull Long id) {
        cacheDemoServiceImpl.delete(id);
    
    }
}
先執行/test/add, 然後/test/list,其次/test/one,你最後會發現的/test/one 當引數傳入相同的時候時,資料是從快取中拿了.

付:下面是springboot不要Ehcache配置檔案的注入方法:

package com.lyz.springboot.thing;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import net.sf.ehcache.config.CacheConfiguration;

/**
 * SpringBoot通過程式碼實現EHCache的配置
 * @author liuyazhuang
 *
 */
@Configuration
@EnableCaching
public class CachingConfiguration implements CachingConfigurer {
	@Bean(destroyMethod = "shutdown")
	public net.sf.ehcache.CacheManager ehCacheManager() {
		CacheConfiguration cacheConfiguration = new CacheConfiguration();
		cacheConfiguration.setName("demo");
		cacheConfiguration.setMemoryStoreEvictionPolicy("LRU");
		cacheConfiguration.setMaxEntriesLocalHeap(1000);
		net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();
		config.addCache(cacheConfiguration);
		return net.sf.ehcache.CacheManager.newInstance(config);
	}

	@Bean
	@Override
	public CacheManager cacheManager() {
		return new EhCacheCacheManager(ehCacheManager());
	}

	@Bean
	@Override
	public KeyGenerator keyGenerator() {
		return new SimpleKeyGenerator();
	}

	@Override
	public CacheResolver cacheResolver() {

		return null;
	}

	@Override
	public CacheErrorHandler errorHandler() {
		return null;
	}

}