Spring Boot緩存實(shí)戰(zhàn) Caffeine

Caffeine和Spring Boot集成

Caffeine是使用Java8對Guava緩存的重寫版本,在Spring Boot 2.0中將取代Guava。如果出現(xiàn)Caffeine,CaffeineCacheManager將會自動(dòng)配置。使用spring.cache.cache-names屬性可以在啟動(dòng)時(shí)創(chuàng)建緩存,并可以通過以下配置進(jìn)行自定義(按順序):

  • spring.cache.caffeine.spec: 定義的特殊緩存
  • com.github.benmanes.caffeine.cache.CaffeineSpec: bean定義
  • com.github.benmanes.caffeine.cache.Caffeine: bean定義

例如,以下配置創(chuàng)建一個(gè)foo和bar緩存,最大數(shù)量為500,存活時(shí)間為10分鐘:

spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

除此之外,如果定義了com.github.benmanes.caffeine.cache.CacheLoader,它會自動(dòng)關(guān)聯(lián)到CaffeineCacheManager。由于該CacheLoader將關(guān)聯(lián)被該緩存管理器管理的所有緩存,所以它必須定義為CacheLoader<Object, Object>,自動(dòng)配置將忽略所有泛型類型。

引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.6.0</version>
</dependency>

開啟緩存的支持

使用@EnableCaching注解讓Spring Boot開啟對緩存的支持

@SpringBootApplication
@EnableCaching// 開啟緩存,需要顯示的指定
public class SpringBootStudentCacheCaffeineApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootStudentCacheCaffeineApplication.class, args);
    }
}

配置文件

新增對緩存的特殊配置,如最大容量、過期時(shí)間等

spring.cache.cache-names=people
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10s,refreshAfterWrite=5s

如果使用了refreshAfterWrite配置還必須指定一個(gè)CacheLoader,如:

/**
 * 必須要指定這個(gè)Bean,refreshAfterWrite=5s這個(gè)配置屬性才生效
 *
 * @return
 */
@Bean
public CacheLoader<Object, Object> cacheLoader() {

    CacheLoader<Object, Object> cacheLoader = new CacheLoader<Object, Object>() {

        @Override
        public Object load(Object key) throws Exception {
            return null;
        }

        // 重寫這個(gè)方法將oldValue值返回回去,進(jìn)而刷新緩存
        @Override
        public Object reload(Object key, Object oldValue) throws Exception {
            return oldValue;
        }
    };

    return cacheLoader;
}

Caffeine配置說明:

  • initialCapacity=[integer]: 初始的緩存空間大小
  • maximumSize=[long]: 緩存的最大條數(shù)
  • maximumWeight=[long]: 緩存的最大權(quán)重
  • expireAfterAccess=[duration]: 最后一次寫入或訪問后經(jīng)過固定時(shí)間過期
  • expireAfterWrite=[duration]: 最后一次寫入后經(jīng)過固定時(shí)間過期
  • refreshAfterWrite=[duration]: 創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過固定的時(shí)間間隔,刷新緩存
  • weakKeys: 打開key的弱引用
  • weakValues:打開value的弱引用
  • softValues:打開value的軟引用
  • recordStats:開發(fā)統(tǒng)計(jì)功能

注意:

  • expireAfterWrite和expireAfterAccess同事存在時(shí),以expireAfterWrite為準(zhǔn)。
  • maximumSize和maximumWeight不可以同時(shí)使用
  • weakValues和softValues不可以同時(shí)使用

示例代碼

/**
 * @author yuhao.wang
 */
@Service
public class PersonServiceImpl implements PersonService {
    private static final Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);

    @Autowired
    PersonRepository personRepository;

    @Override
    @CachePut(value = "people", key = "#person.id")
    public Person save(Person person) {
        Person p = personRepository.save(person);
        logger.info("為id、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
        return p;
    }

    @Override
    @CacheEvict(value = "people")//2
    public void remove(Long id) {
        logger.info("刪除了id、key為" + id + "的數(shù)據(jù)緩存");
        //這里不做實(shí)際刪除操作
    }

    /**
     * Cacheable
     * value:緩存key的前綴。
     * key:緩存key的后綴。
     * sync:設(shè)置如果緩存過期是不是只放一個(gè)請求去請求數(shù)據(jù)庫,其他請求阻塞,默認(rèn)是false。
     */
    @Override
    @Cacheable(value = "people", key = "#person.id", sync = true)
    public Person findOne(Person person, String a, String[] b, List<Long> c) {
        Person p = personRepository.findOne(person.getId());
        logger.info("為id、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
        return p;
    }

    @Override
    @Cacheable(value = "people1")//3
    public Person findOne1() {
        Person p = personRepository.findOne(2L);
        logger.info("為id、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
        return p;
    }

    @Override
    @Cacheable(value = "people2")//3
    public Person findOne2(Person person) {
        Person p = personRepository.findOne(person.getId());
        logger.info("為id、key為:" + p.getId() + "數(shù)據(jù)做了緩存");
        return p;
    }
}

參考:

源碼:
https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

spring-boot-student-cache-caffeine 工程

為監(jiān)控而生的多級緩存框架 layering-cache這是我開源的一個(gè)多級緩存框架的實(shí)現(xiàn),如果有興趣可以看一下

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,290評論 6 342
  • afinalAfinal是一個(gè)android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,907評論 2 45
  • 此篇翻譯的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤閱讀 6,968評論 0 21
  • 1、當(dāng)一個(gè)事件發(fā)生后,事件會從父控件傳給子控件,也就是說由UIApplication -> UIWindow ->...
    雪_晟閱讀 222評論 0 0

友情鏈接更多精彩內(nèi)容