ehcache在java中久負盛名,在springboot中只需要一個配置文件就可以將ehcache集成到項目中。
下面開始演示
github:https://github.com/fengqing11/springboot-ehcache
完整項目結構圖:
創建項目,pom文件如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>xyz.fengqing11</groupId>
<artifactId>sprigboot-cache</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sprigboot-cache</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加緩存配置文件,需要開發者在resources目錄下新建一個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/cache"/>
<!--
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="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="book_cache"
eternal="false"
maxElementsInMemory="5000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
開啓緩存,需要在項目入口做如下修改:
package xyz.fengqing11.sprigbootcache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class SprigbootCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SprigbootCacheApplication.class, args);
}
}
創建Book實體類,需要實現Serializable接口:
package xyz.fengqing11.sprigbootcache.pojo;
import java.io.Serializable;
public class Book implements Serializable {
private Integer id;
private String name;
private String author;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
}
創建BookDao:
package xyz.fengqing11.sprigbootcache.dao;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import xyz.fengqing11.sprigbootcache.pojo.Book;
@Repository
@CacheConfig(cacheNames = "book_cache")
public class BookDao {
@Cacheable
public Book getBookById(Integer id){
System.out.println("getBookById");
Book book = new Book();
book.setId(id);
book.setAuthor("羅貫中");
book.setName("三國演義");
return book;
}
@CachePut(key = "#book.id")
public Book updateBookById(Book book){
System.out.println("uopdateBookById");
book.setName("三國演義2");
return book;
}
@CacheEvict(key = "#id")
public void deleteBookById(Integer id){
System.out.println("deleteBookById");
}
}
創建測試類:
package xyz.fengqing11.sprigbootcache;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import xyz.fengqing11.sprigbootcache.dao.BookDao;
import xyz.fengqing11.sprigbootcache.pojo.Book;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestDao {
@Autowired
BookDao bookDao;
@Test
public void contextLoad() {
bookDao.getBookById(1);
bookDao.getBookById(1);
bookDao.deleteBookById(1);
Book book = bookDao.getBookById(1);
System.out.println("book:" + book);
Book b = new Book();
b.setName("三國演義");
b.setAuthor("羅貫中");
b.setId(1);
bookDao.updateBookById(b);
Book b1 = bookDao.getBookById(1);
System.out.println(b1);
}
}
運行結果:
(這個方法已經是第二次執行了,所以兩個測試方法都是直接使用緩存中的數據,而沒有查詢真正的調用getBookById方法)
-end-