分享一個本地緩存解決方案 Caffeine Cache


關於Caffeine Cache

Google Guava Cache是一種非常優秀本地緩存解決方案,提供了基於容量,時間和引用的緩存回收方式。基於容量的方式內部實現采用LRU算法,基於引用回收很好的利用了Java虛擬機的垃圾回收機制。其中的緩存構造器CacheBuilder采用構建者模式提供了設置好各種參數的緩存對象,緩存核心類LocalCache里面的內部類Segment與jdk1.7及以前的ConcurrentHashMap非常相似,都繼承於ReetrantLock,還有六個隊列,以實現豐富的本地緩存方案。 ​ 通俗的講,Guva是google開源的一個公共java庫,類似於Apache Commons,它提供了集合,反射,緩存,科學計算,xml,io等一些工具類庫。cache只是其中的一個模塊。使用Guva cache能夠方便快速的構建本地緩存。

Caffeine是使用Java8對Guava緩存的重寫版本,在Spring Boot 2.0中將取代Guava。如果出現Caffeine,CaffeineCacheManager將會自動配置。

1.1.1 為什么要用本地緩存

相對於IO操作 速度快,效率高 相對於Redis Redis是一種優秀的分布式緩存實現,受限於網卡等原因,遠水救不了近火

-- 下面來看看,各種本地緩存框架的讀寫對比

 

 引入依賴:

  <!-- springboot 緩存-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!-- caffeine 依賴-->
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
        </dependency>

在啟動類上加入注解:

 

 

 

Caffeine在springboot中集成非常簡單,可以通過配置文件來設置

spring:
  cache:
    cache-names: outLimit,notOutLimit
    caffeine:
      spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s,refreshAfterWrite=7s
    type: caffeine

  

或者使用注解的形式注入 

package cn.aiaudit.model.config;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

/**
 *配置caffeine作為模型的本地緩存
 */
@Configuration
public class CacheConfig {

    @Bean
    public Cache caffeineCache() {
        return Caffeine.newBuilder()
                // 設置最后一次寫入或訪問后經過固定時間過期
                .expireAfterWrite(60, TimeUnit.SECONDS)
                // 初始的緩存空間大小
                .initialCapacity(100)
                // 緩存的最大條數
                .maximumSize(500)
                .build();
    }

}

 下面介紹獲取和存儲緩存數據,可以基於注解的形式,也可以使用手動的形式

1.

  @Autowired
    Cache<String, Object> caffeineCache;
caffeineCache.put(String.valueOf(po.getId()), vo);



// 先從緩存讀取
        caffeineCache.getIfPresent(id);
        SqlInsertIntoProgressVO vo = (SqlInsertIntoProgressVO)caffeineCache.asMap().get(id);

2.

@Slf4j
@Service
@CacheConfig(cacheNames = "caffeineCacheManager")
public class UserInfoServiceImpl implements UserInfoService {

    /**
     * 模擬數據庫存儲數據
     */
    private HashMap<Integer, UserInfo> userInfoMap = new HashMap<>();

    @Override
    @CachePut(key = "#userInfo.id")
    public void addUserInfo(UserInfo userInfo) {
        log.info("create");
        userInfoMap.put(userInfo.getId(), userInfo);
    }

    @Override
    @Cacheable(key = "#id")
    public UserInfo getByName(Integer id) {
        log.info("get");
        return userInfoMap.get(id);
    }

    @Override
    @CachePut(key = "#userInfo.id")
    public UserInfo updateUserInfo(UserInfo userInfo) {
        log.info("update");
        if (!userInfoMap.containsKey(userInfo.getId())) {
            return null;
        }
        // 取舊的值
        UserInfo oldUserInfo = userInfoMap.get(userInfo.getId());
        // 替換內容
        if (!StringUtils.isEmpty(oldUserInfo.getAge())) {
            oldUserInfo.setAge(userInfo.getAge());
        }
        if (!StringUtils.isEmpty(oldUserInfo.getName())) {
            oldUserInfo.setName(userInfo.getName());
        }
        if (!StringUtils.isEmpty(oldUserInfo.getSex())) {
            oldUserInfo.setSex(userInfo.getSex());
        }
        // 將新的對象存儲,更新舊對象信息
        userInfoMap.put(oldUserInfo.getId(), oldUserInfo);
        // 返回新對象信息
        return oldUserInfo;
    }

    @Override
    @CacheEvict(key = "#id")
    public void deleteById(Integer id) {
        log.info("delete");
        userInfoMap.remove(id);
    }

  -- 以上

  

  


免責聲明!

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



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