SpringBoot整合Caffeine本地緩存

一、Caffeine性能

二、Caffeine配置

注意:

1、weakValues 和 softValues 不可以同時使用。
2、maximumSize 和 maximumWeight 不可以同時使用。
3、expireAfterWrite 和 expireAfterAccess 同事存在時,以 expireAfterWrite 爲準。

三、軟引用和弱引用

軟引用:如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。

弱引用:弱引用的對象擁有更短暫的生命週期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存
// 軟引用
Caffeine.newBuilder().softValues().build();

// 弱引用
Caffeine.newBuilder().weakKeys().weakValues().build();

四、SpringBoot 集成 Caffeine 兩種方式

SpringBoot 有兩種使用 Caffeine 作爲緩存的方式:

  • 方式一:直接引入 Caffeine 依賴,然後使用 Caffeine 方法實現緩存。
  • 方式二:引入 Caffeine 和 Spring Cache 依賴,使用 SpringCache 註解方法實現緩存。

1、SpringBoot 集成 Caffeine 方式一

1、Maven 引入相關依賴

<dependency>
       <groupId>com.github.ben-manes.caffeine</groupId>
       <artifactId>caffeine</artifactId>
</dependency>

2、配置緩存配置類

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;

@Configuration
public class CacheConfig {

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

}

3、需要本地緩存的位置引入配置對象調用方法

@Slf4j
@Service
public class UserInfoServiceImpl implements UserInfoService {

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

    @Autowired
    Cache<String, Object> caffeineCache;

    @Override
    public void addUserInfo(UserInfo userInfo) {
        log.info("create");
        userInfoMap.put(userInfo.getId(), userInfo);
        // 加入緩存
        caffeineCache.put(String.valueOf(userInfo.getId()),userInfo);
    }

    @Override
    public UserInfo getByName(Integer id) {
        // 先從緩存讀取
        caffeineCache.getIfPresent(id);
        UserInfo userInfo = (UserInfo) caffeineCache.asMap().get(String.valueOf(id));
        if (userInfo != null){
            return userInfo;
        }
        // 如果緩存中不存在,則從庫中查找
        log.info("get");
        userInfo = userInfoMap.get(id);
        // 如果用戶信息不爲空,則加入緩存
        if (userInfo != null){
            caffeineCache.put(String.valueOf(userInfo.getId()),userInfo);
        }
        return userInfo;
    }

    @Override
    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);
        // 替換緩存中的值
        caffeineCache.put(String.valueOf(oldUserInfo.getId()),oldUserInfo);
        return oldUserInfo;
    }

    @Override
    public void deleteById(Integer id) {
        log.info("delete");
        userInfoMap.remove(id);
        // 從緩存中刪除
        caffeineCache.asMap().remove(String.valueOf(id));
    }

}

2、SpringBoot 集成 Caffeine 方式二

1、Maven 引入相關依賴

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

2、配置類

@Configuration
public class CacheConfig {

    /**
     * 配置緩存管理器
     *
     * @return 緩存管理器
     */
    @Bean("caffeineCacheManager")
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
                // 設置最後一次寫入或訪問後經過固定時間過期
                .expireAfterAccess(60, TimeUnit.SECONDS)
                // 初始的緩存空間大小
                .initialCapacity(100)
                // 緩存的最大條數
                .maximumSize(1000));
        return cacheManager;
    }

}

3、使用

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

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