1. 程式人生 > >springBoot整合ecache快取

springBoot整合ecache快取

EhCache 是一個純Java的程序內快取框架,具有快速、精幹等特點,是Hibernate中預設的CacheProvider。

  ehcache提供了多種快取策略,主要分為記憶體和磁碟兩級,所以無需擔心容量問題。

  spring-boot是一個快速的整合框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。

  由於spring-boot無需任何樣板化的配置檔案,所以spring-boot整合一些其他框架時會有略微的不同。

  1.spring-boot是一個通過maven管理的jar包的框架,整合ehcache需要的依賴如下

 <dependency>
    <groupId>org.springframework</groupId>
     <artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
         <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
          <version>2.8.3</version>
</dependency>      
2.使用ehcache,我們需要一個ehcache.xml來定義一些cache的屬性。
<?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 path="java.io.tmpdir/Tmp_EhCache" />
           <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" timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU" />

</ehcache>

解釋下這個xml檔案中的標籤。

  (1).diskStore: 為快取路徑,ehcache分為記憶體和磁碟兩級,此屬性定義磁碟的快取位置。引數解釋如下:    
             user.home – 使用者主目錄
             user.dir  – 使用者當前工作目錄
             java.io.tmpdir – 預設臨時檔案路徑

  (2).defaultCache:預設快取策略,當ehcache找不到定義的快取時,則使用這個快取策略。只能定義一個。

       (3).cache:自定快取策略,為自定義的快取策略。引數解釋如下:

    cache元素的屬性:   
            name:快取名稱                  
            maxElementsInMemory:記憶體中最大快取物件數                  
            maxElementsOnDisk:硬碟中最大快取物件數,若是0表示無窮大                  
            eternal:true表示物件永不過期,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性,預設為false                
            overflowToDisk:true表示當記憶體快取的物件數目達到了maxElementsInMemory界限後,會把溢位的物件寫到硬碟快取中。注意:如果快取的物件要寫入到硬碟中的話,則該物件必須實現了Serializable接口才行。                  
            diskSpoolBufferSizeMB:磁碟快取區大小,預設為30MB。每個Cache都應該有自己的一個快取區。               
            diskPersistent:是否快取虛擬機器重啟期資料                  
            diskExpiryThreadIntervalSeconds:磁碟失效執行緒執行時間間隔,預設為120秒     
            timeToIdleSeconds: 設定允許物件處於空閒狀態的最長時間,以秒為單位。當物件自從最近一次被訪問後,如果處於空閒狀態的時間超過了timeToIdleSeconds屬性值,這個物件就會過期,EHCache將把它從快取中清空。只有當eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示物件可以無限期地處於空閒狀態                  
            timeToLiveSeconds:設定物件允許存在於快取中的最長時間,以秒為單位。當物件自從被存放到快取中後,如果處於快取中的時間超過了 timeToLiveSeconds屬性值,這個物件就會過期,EHCache將把它從快取中清除。只有當eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示物件可以無限期地存在於快取中。timeToLiveSeconds必須大於timeToIdleSeconds屬性,才有意義     
            memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。可選策略有:LRU(最近最少使用,預設策略)、FIFO(先進先出)、LFU(最少訪問次數)。  

 

  3.將ehcache的管理器暴露給spring的上下文容器,

@Configuration
// 標註啟動了快取
@EnableCaching
public class CacheConfiguration {

    /*
     * ehcache 主要的管理器
     */
    @Bean(name = "appEhCacheCacheManager")
    public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean){
        return new EhCacheCacheManager (bean.getObject ());
    }

    /*
     * 據shared與否的設定,Spring分別通過CacheManager.create()或new CacheManager()方式來建立一個ehcache基地.
     */
    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();
        cacheManagerFactoryBean.setConfigLocation (new ClassPathResource ("conf/ehcache-app.xml"));
        cacheManagerFactoryBean.setShared (true);
        return cacheManagerFactoryBean;
    }
}

 @Configuration:為spring-boot註解,主要標註此為配置類,優先掃描。

      @Bean:向spring容器中加入bean。

  至此所有的配置都做好了,通過spring-boot進行整合框架就是這麼簡單。

  4.使用ehcache

    使用ehcache主要通過spring的快取機制,上面我們將spring的快取機制使用了ehcache進行實現,所以使用方面就完全使用spring快取機制就行了。
    具體牽扯到幾個註解:

    @Cacheable:負責將方法的返回值加入到快取中,引數3
    @CacheEvict:負責清除快取,引數4

     引數解釋:

    value:快取位置名稱,不能為空,如果使用EHCache,就是ehcache.xml中宣告的cache的name
    key:快取的key,預設為空,既表示使用方法的引數型別及引數值作為key,支援SpEL
    condition:觸發條件,只有滿足條件的情況才會加入快取,預設為空,既表示全部都加入快取,支援SpEL

    allEntries:CacheEvict引數,true表示清除value中的全部快取,預設為false

  不多說,直接上程式碼:

@Service
public class CacheDemoServiceImpl implements CacheDemoService {

    /**
     * 快取的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)
    @Override
    public void create(Thing thing){
        Long id = getNextId ();
        thing.setId (id);
        data.put (id, thing);
    } 
      
     @Cacheable(value = DEMO_CACHE_NAME,key = "#thing.getId()+'thing'")
    @Override
    public Thing findById(Long id){
        System.err.println ("沒有走快取!" + id);
        return data.get (id);
    }

      @Cacheable(value = DEMO_CACHE_NAME,key = THING_ALL_KEY)
    @Override
    public List<Thing> findAll(){
        return Lists.newArrayList (data.values ());
    }
   
   
      @Override
    @CachePut(value = DEMO_CACHE_NAME,key = "#thing.getId()+'thing'")
    @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)
    @Override
    public void delete(Long id){
        data.remove (id);
    }
   
}
5.只需要通過註解在service層方法上打註解便可以使用快取,在find**上存入快取,在delete**,update**上清除快取。
具體pom.xml檔案如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lclc.boot</groupId>
    <artifactId>boot-cache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.1.3.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>17.0</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.8.3</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/snapshot</url>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <url>http://repo.spring.io/milestone</url>
        </pluginRepository>
    </pluginRepositories>

</project>