【Spring Boot】Ehcache2.x緩存實戰總結

最近貓哥在研究SpringBoot緩存,在這裏對SpringBoot的Ehcache2.x緩存做一個總結梳理,順便貼一下自己寫的實戰代碼,以供參考。

SpringBoot緩存

Spring3.1中開始對緩存提供支持,核心思路是對方法的緩存,當開發者調用一個方法時,將方法的參數和返回值作爲key/value緩存起來,當再次調用該方法時,如果緩存中有數據,就直接從緩存中獲取,否則再去執行該方法。但是,Spring中未提供緩存的實現,而是提供了一套緩存API,開發者可以自由選擇緩存的實現,目前SpringBoot支持的緩存有如下幾種:

  • JCache(JSR-107)
  • EnCache2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine
  • Simple

這裏主要介紹目前常用的緩存實現之一:EnCache2.x。由於Spring早已將緩存領域統一,因此無論使用哪種緩存實現,不同的只是緩存配置,開發者使用的緩存註解是一致的。

EnCache2.x緩存

在SpringBoot中,EnCache2.x緩存的使用十分常見,實現也比較容易,只需一個配置文件就可以將EnCache集成到項目中。EnCache2.x的使用具體步驟如下。

  1. 創建項目,添加依賴

    創建Spring Boot項目,添加spring-boot-starter-cache依賴以及Encache依賴,代碼如下:

    
    <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>

     

  2. 添加緩存配置文件

    如果Encache的依賴存在,並且在classpath下面有一個名爲encache.xml的Encache的配置文件,那麼EnCacheCacheManager會自動作爲緩存的實現。因此,在resources目錄下創建encache.xml文件作爲Encache緩存的配置文件,代碼如下:
     

    
    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache>
        <diskStore path="java.io.tmpdir/cache"/>
        <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />
        <cache name="book_cache"
               maxElementsInMemory="10000"
               eternal="true"
               timeToIdleSeconds="120"
               timeToLiveSeconds="120"
               overflowToDisk="true"
               diskPersistent="true"
               diskExpiryThreadIntervalSeconds="600"
            />
    </ehcache>

    這是一個常規的Encache配置文件,提供了兩個緩存策略,一個是默認的,一個是名爲book_cache。另外,如果你想自定義Encache配置文件的名稱和位置,可以在application.properties中添加如下配置:
     

    spring.cache.ehcache.config=classpath:config/another-config.xml

     

  3. 開啓緩存
    在項目的入口類上添加@EnableCaching註解開啓緩存,代碼如下:

    
    @SpringBootApplication
    @EnableCaching
    public class MavenprojectApplication {
        public static void main(String[] args) {
            SpringApplication.run(MarvenprojectApplication.class, args);
        }
    }

     

  4. 創建Book實體類和BookService,代碼如下:
     

    
    public class BookBean implements Serializable {
    
        private Integer id;
    
        private String name;
    
        private String author;
    
        public Integer getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAuthor(String author) {
            this.author = author;
        }
    }
    
    @Repository
    @CacheConfig(cacheNames = "book_cache")
    public class BookDao {
        @Cacheable
        public BookBean getBookById(Integer id){
            System.out.println("getBookById");
            BookBean book = new BookBean();
            book.setId(id);
            book.setName("三國演義");
            book.setAuthor("羅貫中");
            return book;
        }
    
        @CachePut(key = "#book.id")
        public BookBean updateBookById(BookBean book){
            System.out.println("updateBookById");
            book.setName("三國演義2");
            return book;
        }
    
        @CacheEvict(key = "#id")
        public void deleteBookById(Integer id){
            System.out.println("deleteBookById");
        }
    }


    ps:相對的@CacheEvict標註在需要清除緩存元素的方法或類上。

  5. 創建測試類
    創建測試類,對Service中的方法進行測試,代碼如下:

     

     

    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class CacheApplicationTests {
        @Autowired
        BookDao bookDao;
        @Test
        public void contextLoads(){
            bookDao.getBookById(1);
            bookDao.getBookById(1);
            bookDao.deleteBookById(1);
    
            BookBean b3 = bookDao.getBookById(1);
            System.out.println("b3:"+b3.getName());
    
            BookBean b = new BookBean();
            b.setName("三國演義2");
            b.setAuthor("羅貫中");
            b.setId(1);
            bookDao.updateBookById(b);
    
            BookBean b4 = bookDao.getBookById(1);
            System.out.println("b4:"+b4.getName());
        }
    }

    ps:使用註解@RunWith(SpringRunner.class),需要首先在pom中引入依賴:
     

    
    <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
    </dependency>
    <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.2.RELEASE</version>
                <scope>compile</scope>
    </dependency>

     

  6. 最後執行測試類,得到打印日誌

    分析:一開始執行了兩個查詢,但是查詢方法只打印了一次,因爲第二次使用了緩存。接下來執行了刪除方法,刪除方法執行完之後再執行查詢方法,查詢方法又被執行了,因爲在刪除方法中緩存已經被刪除了。再接下來執行了更新方法,更新方法中不僅更新了數據,也更新了緩存,所以在最後的查詢方法中,查詢方法日誌沒打印,說明該方法沒執行,而是使用了緩存中的數據,而緩存中的數據已經被更新了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章