欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot淺析緩存機(jī)制之Ehcache?2.x應(yīng)用

 更新時(shí)間:2022年08月13日 09:17:35   作者:一只小熊貓呀  
EhCache?是一個(gè)純Java的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn)。它是Hibernate中的默認(rèn)緩存框架。Ehcache已經(jīng)發(fā)布了3.1版本。但是本文的講解基于2.x版本

介紹

Spring 3.1 中開始對(duì)緩存提供支持,核心思路是對(duì)方法的緩存,當(dāng)開發(fā)者調(diào)用一個(gè)方法時(shí),將方法的參數(shù)和返回值作為 key/value 緩存起來,當(dāng)再次調(diào)用改方法時(shí),如果緩存中有數(shù)據(jù),就直接從緩存中獲取,否則再去執(zhí)行該方法。但是,Spring 中并未提供緩存的實(shí)現(xiàn),而是提供了一套緩存 API ,開發(fā)者可以自由選擇緩存的實(shí)現(xiàn),目前 Spring Boot 支持的緩存有如下幾種:

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

此處只介紹常用的緩存實(shí)現(xiàn) Ehcache 2.x 和 Redis,由于 Spring 早已將緩存領(lǐng)域統(tǒng)一,因此無論使用哪種緩存實(shí)現(xiàn),不同的只是緩存配置,開發(fā)者使用的緩存注解是一致的(Spring 緩存注解和各種緩存實(shí)現(xiàn)的關(guān)系就像 JDBC 和各種數(shù)據(jù)庫驅(qū)動(dòng)的關(guān)系一樣)。

Ehcache 2.x 緩存

Ehcache 緩存在Java開發(fā)領(lǐng)域久負(fù)盛名,在Spring Boot 中,只需要一個(gè)配置文件就可以將 Ehcache 集成到項(xiàng)目中。步驟如下:

1. 創(chuàng)建項(xiàng)目添加緩存依賴

創(chuàng)建 Spring Boot 項(xiàng)目,添加 spring-boot-starter-cache 依賴以及 Ehcache 依賴

<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-test</artifactId>
  <scope>test</scope>
</dependency>

2. 添加緩存配置文件

如果 Ehcache 的依賴存在,并且在 classpath 下有一個(gè)名為 echache.xml 的 Ehcache 配置文件,那么 EhCacheCacheManager 將會(huì)自動(dòng)作為緩存的實(shí)現(xiàn)。因此,在 resources 目錄下創(chuàng)建 ehcache.xml 文件作為 Ehcache 緩存的配置文件,如下:

<ehcache>
    <diskStore path="java.io.tmpdir/cache"/>
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />
    <!--
        name:緩存名稱
        maxElementsInMemory:緩存最大個(gè)數(shù)
        eternal:緩存對(duì)象是否永久有效。一旦設(shè)置了永久有效,timeout將不起作用
        timeToIdleSeconds:緩存對(duì)象在失效前允許閑置時(shí)間(秒),當(dāng)eternal為false時(shí)生效
        timeToLiveSeconds:緩存對(duì)象在失效前允許存活的時(shí)間(秒),當(dāng)eternal為false時(shí)生效
        overflowToDisk:當(dāng)內(nèi)存中的對(duì)象數(shù)量達(dá)到maxElementsInMemory時(shí), Ehcache 是否將對(duì)象寫到磁盤中
        diskExpiryThreadIntervalSeconds:磁盤失效線程運(yùn)行時(shí)間間隔
    -->
    <cache name="book_cache"
           maxElementsInMemory="10000"
           eternal="true"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="600"/>
</ehcache>

這是一個(gè)常規(guī)的 Ehcache 配置文件,提供了兩個(gè)緩存策略,一個(gè)是默認(rèn)的,另一個(gè)名為 book_cache 。還有更為詳細(xì)的 Ehcache 配置,此處不再一一介紹。如果開發(fā)者想自定義 Ehcache 配置文件的名稱和位置,可以在 application.properties 中添加如下配置:

spring.cache.ehcache.config=classpath:ehcache2.xml

3. 開啟緩存

在項(xiàng)目的入口類添加 @EnableCaching 注解開啟緩存,如下

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

4. 創(chuàng)建 BookDao

Book

public class Book implements Serializable {
    private Integer id;
    private String name;
    private String author;
    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", author='" + 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;
    }
}

BookDao

@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.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");
    }
}

代碼解釋:

在 BookDao 上添加 @CacheConfig 注解指明使用的緩存名字,這個(gè)配置可選,若不使用 @CacheConfig ,則直接在 @Cacheable 注解中指明緩存名字

在 getBookById 方法上添加 @Cacheable 注解表示對(duì)該方法進(jìn)行緩存,默認(rèn)情況下,緩存的key是方法的參數(shù),緩存的 value 是方法的返回值。當(dāng)開發(fā)者在其他類中調(diào)用該方法時(shí),首先會(huì)根據(jù)調(diào)用參數(shù)查看緩存中是否有相關(guān)數(shù)據(jù),若有,則直接使用緩存數(shù)據(jù),該方法不會(huì)執(zhí)行,否則執(zhí)行該方法,執(zhí)行成功后將返回值緩存起來,但若是在當(dāng)前類中調(diào)用該方法,則緩存不會(huì)生效

@Cacheable 注解中還有一個(gè)屬性 condition 用來描述緩存的執(zhí)行時(shí)機(jī),例如 @Cacheable(“#id%2==0”) 表示 id 對(duì) 2 取模為0時(shí)才進(jìn)緩存,否則不緩存

如果開發(fā)者不想使用默認(rèn)到的 key ,也可以像 updateBookById 和 deleteBookById 一樣自定義 key,@CachePut(key = “#book.id”) 表示緩存的key 為參數(shù)book 對(duì)象中 id 的值,@CacheEvict(key = “#id”)表示緩存的key為參數(shù)id。除了這種使用參數(shù)定義 key 的方式外,Spring 還提供了一個(gè) root 對(duì)象用來生成 key ,如圖

| 屬性名稱 | 屬性描述 | 用法示例 |

| — | — | — |

| methodName | 當(dāng)前方法名 | #root.methodName |

| method | 當(dāng)前方法對(duì)象 | #root.method.name |

| caches | 當(dāng)前方法使用的緩存 | #root.caches[0].name |

| target | 當(dāng)前被調(diào)用的對(duì)象 | #root.target |

| targetClass | 當(dāng)前被調(diào)用的對(duì)象的class | #root.targetClass |

| args | 當(dāng)前方法參數(shù)數(shù)組 | #root.args[0] |

如果這些 key 不能滿足開發(fā)需求,開發(fā)者也可以自定義緩存 key 的生成器 KeyGenerator,如下

@Component
public class MyKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
        return Arrays.toString(params);
    }
}

然后在 @Cacheable 注解中引用 MyKeyGenerator 實(shí)例即可

@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");
    }
}

MyKeyGenerator 中的 generate 方法的參數(shù)分別是當(dāng)前對(duì)象、當(dāng)前請(qǐng)求的方法以及方法的參數(shù),開發(fā)者可根據(jù)這些信息組成一個(gè)新的 key 返回,返回值就是緩存的 key。

  • @CachePut 注解一般用于數(shù)據(jù)更新方法上,與 @Cacheable 注解不同,添加了 @CachePut 注解的方法每次在執(zhí)行時(shí)都不去檢查緩存中是否有數(shù)據(jù),而是直接執(zhí)行方法,然后將方法的執(zhí)行結(jié)果緩存起來,如果 key 對(duì)應(yīng)的數(shù)據(jù)已經(jīng)被緩存起來了,就會(huì)覆蓋之前的數(shù)據(jù),這樣可以避免再次加載數(shù)據(jù)時(shí)獲取到臟數(shù)據(jù)。同時(shí) @CachePut 具有和 @Cacheable 類似的屬性
  • @CacheEvict 注解一般用于刪除方法上,表示移除一個(gè) key 對(duì)應(yīng)的緩存。@CacheEvict 注解由兩個(gè)特殊屬性:allEntries 和 beforeInvocation,其中 allEntries 表示是否將所有的緩存數(shù)據(jù)都移除,默認(rèn)為 false,beforeInvocation 表示是否在方法執(zhí)行之前移除緩存中的數(shù)據(jù),默認(rèn)為 false ,即在方法執(zhí)行之后移除緩存中的數(shù)據(jù) 5. 創(chuàng)建測(cè)試類

5 .創(chuàng)建測(cè)試類

對(duì) Service 中的方法進(jìn)行測(cè)試

@RunWith(SpringRunner.class)
@SpringBootTest
public class CacheApplicationTests {
    @Autowired
    BookDao bookDao;
    @Test
    public void contextLoads() {
        bookDao.deleteBookById(1);
        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);
    }
}

執(zhí)行該方法,控制臺(tái)打印日志如下:

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

為了防止來回測(cè)試緩存的影響,這里先執(zhí)行刪除操作(同時(shí)也會(huì)刪除緩存)。然后執(zhí)行了一次查詢,正常打印,接著又執(zhí)行了一次查詢沒打印(直接讀取的緩存),然后執(zhí)行刪除,接著再執(zhí)行查詢正常打?。▌h除操作也刪除了緩存),再接著執(zhí)行更新操作(同時(shí)更新了緩存),最后再次查詢,打印更新后的數(shù)據(jù)。

到此這篇關(guān)于SpringBoot淺析緩存機(jī)制之Ehcache 2.x應(yīng)用的文章就介紹到這了,更多相關(guān)SpringBoot Ehcache 2.x內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RabbitMq中channel接口的幾種常用參數(shù)詳解

    RabbitMq中channel接口的幾種常用參數(shù)詳解

    這篇文章主要介紹了RabbitMq中channel接口的幾種常用參數(shù)詳解,RabbitMQ 不會(huì)為未確認(rèn)的消息設(shè)置過期時(shí)間,它判斷此消息是否需要重新投遞給消費(fèi)者的唯一依據(jù)是消費(fèi)該消息的消費(fèi)者連接是否己經(jīng)斷開,需要的朋友可以參考下
    2023-08-08
  • java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能

    java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)在SSM下使用支付寶掃碼支付功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • springboot 接收List 入?yún)⒌膸追N方法

    springboot 接收List 入?yún)⒌膸追N方法

    本文主要介紹了springboot 接收List 入?yún)⒌膸追N方法,本文主要介紹了7種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • Spring AOP事務(wù)管理的示例詳解

    Spring AOP事務(wù)管理的示例詳解

    這篇文章將通過轉(zhuǎn)賬案例為大家詳細(xì)介紹一下Spring AOP是如何進(jìn)行事務(wù)管理的,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-06-06
  • SpringCloud的Config配置中心詳解

    SpringCloud的Config配置中心詳解

    這篇文章主要介紹了SpringCloud的Config配置中心詳解,SpringCloud Config為微服務(wù)架構(gòu)中的微服務(wù)提供集中化的外部配置支持,配置服務(wù)器為各個(gè)不同微服務(wù)應(yīng)用的所有環(huán)境提供了一個(gè)中心化的外部配置,需要的朋友可以參考下
    2023-07-07
  • Java調(diào)用計(jì)算機(jī)攝像頭拍照實(shí)現(xiàn)過程解析

    Java調(diào)用計(jì)算機(jī)攝像頭拍照實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Java調(diào)用計(jì)算機(jī)攝像頭拍照實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • SpringBoot實(shí)現(xiàn)登錄攔截的示例代碼

    SpringBoot實(shí)現(xiàn)登錄攔截的示例代碼

    如果我們不進(jìn)行登錄攔截的話,即使我們跳過登錄頁面直接去訪問任意一個(gè)頁面也能訪問成功,那么登錄功能就沒有意義,同時(shí)也會(huì)存在安全問題,本文就來介紹一下SpringBoot登錄攔截,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • spring中@Autowire和@Resource的區(qū)別在哪里(推薦)

    spring中@Autowire和@Resource的區(qū)別在哪里(推薦)

    這篇文章主要介紹了spring中@Autowire和@Resource的區(qū)別在哪里?本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • Java輸出通過InetAddress獲得的IP地址數(shù)組詳細(xì)解析

    Java輸出通過InetAddress獲得的IP地址數(shù)組詳細(xì)解析

    由于byte被認(rèn)為是unsigned byte,所以最高位的1將會(huì)被解釋為符號(hào)位,另外Java中存儲(chǔ)是按照補(bǔ)碼存儲(chǔ),所以1000 0111會(huì)被認(rèn)為是補(bǔ)碼形式,轉(zhuǎn)換成原碼便是1111 0001,轉(zhuǎn)換成十進(jìn)制數(shù)便是-121
    2013-09-09
  • 基于Mybatis-Plus攔截器實(shí)現(xiàn)MySQL數(shù)據(jù)加解密的示例代碼

    基于Mybatis-Plus攔截器實(shí)現(xiàn)MySQL數(shù)據(jù)加解密的示例代碼

    用戶的一些敏感數(shù)據(jù),例如手機(jī)號(hào)、郵箱、身份證等信息,在數(shù)據(jù)庫以明文存儲(chǔ)時(shí)會(huì)存在數(shù)據(jù)泄露的風(fēng)險(xiǎn),因此需要進(jìn)行加密,解密等功能,接下來本文就給大家介紹基于Mybatis-Plus攔截器實(shí)現(xiàn)MySQL數(shù)據(jù)加解密,需要的朋友可以參考下
    2023-07-07

最新評(píng)論