SpringBoot緩存 --(一)EhCache2.X


簡介:

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

  目前Spring Boot支持的緩存有如下幾種::  

  JCache (JSR-107)
  EhCache 2.x
  Hazelcast
  Infinispan
  Couchbase
  Redis
  Caffeine
  Simple

 

使用:

pom.xml

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

Encache配置文件:ehcache.xml

  這是一個常規的Ehcache 配置文件,提供了兩個緩存策略,一個是默認的,另一個名為book _cache。

   其中,name表示緩存名稱:

   maxElementsInMemory 表示緩存最大個數:

   etemal 表示緩存對象是否永久有效,一旦設置了永久有效,timcout 將不起作用:

   timeToldleSeconds 表示緩存對象在失效前的允許閑置時間(單位:秒),當etermal對象不是永久有效時,該屬性才生效:

   timeToLiveSeconds表示緩存對象在失效前允許存活的時間(單位:秒),當eternal-false對象不是永久有效時,該屬性才生效:

   overflowToDisk 表示當內存中的對象數量達到maxElementsInMemory時,Eheache 是否將對象寫到磁盤中:

   diskxpiryTheadntervalseconds 表示磁盤失效線程運行時間間隔。

<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="10"/>
</ehcache>

開啟緩存:@EnableCaching注解

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

創建實體類和service

public class Book implements Serializable {
    private Integer id;
    private String name;
    private String author;

。。。。。
}
@Service
@CacheConfig(cacheNames = "book_cache") public class BookDao {
    @Autowired
    MyKeyGenerator myKeyGenerator;
@Cacheable(keyGenerator
= "myKeyGenerator") public Book getBookById(Integer id) { System.out.println("getBookById"); Book book = new Book(); book.setId(id); book.setName("三國演義"); book.setAuthor("羅貫中"); return book; } @CachePut(key = "#book.id") public Book updateBookById(Book book) { System.out.println("updateBookById"); book.setName("三國演義2"); return book; } @CacheEvict(key = "#id") public void deleteBookById(Integer id) { System.out.println("deleteBookById"); } }

  在Service層上添加@CacheConfig注解指明使用的緩存的名字,這個配置可選,若不使用@CacheConfig注解,則直接在@Cacheable注解中指明緩存名字。

  在getBookById方法上添加@Cacheable注解表示對該方法進行緩存,默認情況下,緩存的key是方法的參數,緩存的value是方法的返回值。當開發者在其他類中調用該方法時,首先會根據調用參數查看緩存中是否有相關數據,若有,則直接使用緩存數據,該方法不會執行,否則執行該方法,執行成功后將返回值緩存起來,但若是在當前類中調用該方法,則緩存不會生效

  @Cacheable注解中還有一個屬性condition用來描述緩存的執行時機,例如@Cacheable(condition= "#id%2= =0")表示當id對2取模為0時才進行緩存,否則不緩存。

  如果開發者不想使用默認的key,也可以自定義key,key = "#book.id"表示緩存的key為參數book對象中id 的值,key = "#id"表示緩存的key為參數id.

  除了這種使用參數定義key的方式之外,Spring 還提供了一個root對象用來生成key,如表。

 

 

   @CachePut注解一般用於數據更新方法上,與@Cacheable 注解不同,添加了@CachePut注解的方法每次在執行時都不去檢查緩存中是否有數據,而是直接執行方法,然后將方法的執行結果緩存起來,如果該key對應的數據已經被緩存起來了,就會覆蓋之前的數據,這樣可以避免再次加載數據時獲取到臟數據。同時,@CachePut具有和@Cacheable類似的屬性,這里不再贅述。

  @CacheEvict注解一般用於刪除方法上,表示移除一個key對應的緩存。@CacheEvict注解有兩個特殊的屬性: allEntries和beforeInvocation, 其中allEntries表示是否將所有的緩存數據都移除,默認為false, beforeInvocation表示是否在方法執行之前移除緩存中的數據,默認為false,即在方法執行之后移除緩存中的數據。

測試:

@RunWith(SpringRunner.class)
@SpringBootTest
public class CacheApplicationTests {
    @Autowired
    BookDao bookDao;
    @Test
    public void contextLoads() {
        bookDao.getBookById(1);
        bookDao.getBookById(1);

        bookDao.deleteBookById(1);

        Book b3 = bookDao.getBookById(1);
        System.out.println("b3:"+b3);

        Book b = new Book();
        b.setName("三國演義");
        b.setAuthor("羅貫中");
        b.setId(1);
        bookDao.updateBookById(b);

        Book b4 = bookDao.getBookById(1);
        System.out.println("b4:"+b4);
    }
}

控制台:

 
         
getBookById
deleteBookById
getBookById
b3:Book{id=1, name='三國演義', author='羅貫中'} 
updateBookById b4:Book{id
=1, name='三國演義', author='羅貫中'}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM