1. 引入jar:
implementation 'com.github.ben-manes.caffeine:caffeine:2.8.4'
implementation('org.springframework.boot:spring-boot-starter-cache')
2. 使用配置类配置
2.1启动类加注解: @EnableCaching
2.2 配置类:
package com.cnpc.cmp.cmpworksheetapp.config;
import com.github.benmanes.caffeine.cache.*;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
/**
* @ClassName CacheConfig
* @Description springboot集成本地缓存caffeine 配置类
* @Date
*/
@Configuration
public class CacheConfig {
@Bean("caffeineCacheManager")
public CacheManager cacheManager(){
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(getCaffeine());
caffeineCacheManager.setCacheLoader(cacheLoader());
//是否允许值为空
caffeineCacheManager.setAllowNullValues(false);
caffeineCacheManager.setCacheNames(Collections.singleton("test"));
return caffeineCacheManager;
}
@Bean
public CacheLoader<Object,Object> cacheLoader(){
return new CacheLoader<Object, Object>() {
@Override
public @Nullable Object load(@NonNull Object key) throws Exception {
// 这里我们就可以从数据库或者其他地方查询最新的数据 ???
return null;
}
@Override
public @Nullable Object reload(@NonNull Object key, @NonNull Object oldValue) throws Exception {
System.out.println("--refresh--:"+key);
return oldValue;
}
};
}
@Bean
public LoadingCache getCache(){
LoadingCache build = getCaffeine().build(cacheLoader());
return build;
}
@Bean
public Caffeine getCaffeine(){
Caffeine caffeine = Caffeine.newBuilder()
//设置过期时间。最后一次写入或访问后过多久过期。
.expireAfterAccess(60, TimeUnit.SECONDS)
//cache的初始容量值
.initialCapacity(100)
//maximumSize用来控制cache的最大缓存数量,maximumSize和maximumWeight(最大权重)不可以同时使用,
.maximumSize(1000)
//弱引用
// .weakKeys()
// .weakValues()
//创建或更新之后多久刷新,需要设置cacheLoader
.refreshAfterWrite(10,TimeUnit.SECONDS)
//缓存写入/删除 监控
.writer(new CacheWriter<Object, Object>() {
@Override
public void write(@NonNull Object key, @NonNull Object value) {
System.out.println("缓存写入: key= "+key+";value="+value);
}
@Override
public void delete(@NonNull Object key, @Nullable Object value, @NonNull RemovalCause cause) {
System.out.println("缓存删除: key= "+key+";value="+value);
}
});
return caffeine;
}
}
3. 使用注解使用缓存:
其中注解解释:
- @Cacheable 触发缓存入口(这里一般放在创建和获取的方法上),当缓存中有是,方法不会执行,直接取缓存中的。如果没有,执行方法然后将返回值存入到缓存中。
- @CacheEvict 触发缓存的eviction(用于删除的方法上)
- @CachePut 更新缓存且不影响方法执行(用于修改的方法上,该注解下的方法始终会被执行)
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Optional;
@Service
public class CacheServiceImpl implements CacheService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserHolidayRepository userHolidayRepository;
@Override
public UserHoliday getByName(String name) {
return null;
}
/**
* 将数据存放到缓存中
* 创建缓存:@Cacheable注解即可自动将数据添加到缓存中,后续直接从缓存中读取数据。
* value:表示缓存的名称;key:表示缓存的key,可以为空。
*
* @param id
* @return
*/
@Cacheable(value = "test", key = "#id")
@Override
public UserHoliday getById(String id) {
logger.info("getById parameter id : {}", id);
Optional<UserHoliday> optional = userHolidayRepository.findById(id);
UserHoliday userHoliday = new UserHoliday();
if (optional.isPresent()) {
userHoliday = optional.get();
}
logger.info("getById return userHoliday:{}", userHoliday);
return userHoliday;
}
/**
* 将满足条件的数据存放到缓存中。
*
* @param id
* @return
* @Cacheable 有一个参数叫做condition,该条件为true时则放到缓存到。该参数同样需使用SpEL表达式。
*/
@Cacheable(value = "test", key = "#id", condition = "#id.equals('2')")
@Override
public UserHoliday getByConditionalId(String id) {
logger.info("getByConditionalId parameter id : {}", id);
Optional<UserHoliday> optional = userHolidayRepository.findById(id);
UserHoliday userHoliday = new UserHoliday();
if (optional.isPresent()) {
userHoliday = optional.get();
}
logger.info("getByConditionalId return userHoliday:{}", userHoliday);
return userHoliday;
}
/**
* 更新缓存
*
* @param holidayDTO
* @return
*/
@CachePut(value = "test", key = "#id")
@Override
public UserHoliday updateRemainDay(String id,HolidayDTO holidayDTO) {
logger.info("updateRemainDay parameter holidayDTO : {}", holidayDTO.toString());
Optional<UserHoliday> byId = userHolidayRepository.findById(holidayDTO.getId());
UserHoliday userHoliday = byId.get();
BeanUtils.copyProperties(holidayDTO, userHoliday);
UserHoliday returnUserHoliday = userHolidayRepository.saveAndFlush(userHoliday);
logger.info("updateRemainDay return returnUserHoliday : {}", returnUserHoliday.toString());
return returnUserHoliday;
}
@CacheEvict(value = "test", key = "#id")
@Override
public void deleteById(String id) {
userHolidayRepository.deleteById(id);
}
}
4. 使用api操作缓存:
4.1注入: @Autowired
LoadingCache syncCache;
4.2 使用:
syncCache.put("a","aaa");
syncCache.getIfPresent("a");
ArrayList<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
syncCache.getAllPresent(strings);
例如:
@Autowired
LoadingCache syncCache;
/**
* 将数据存放到缓存中
* 创建缓存:@Cacheable注解即可自动将数据添加到缓存中,后续直接从缓存中读取数据。
* value:表示缓存的名称;key:表示缓存的key,可以为空。
*/
@Cacheable(value = "test", key = "#id")
@Override
public UserHoliday getById(String id) {
syncCache.put("a","aaa");
syncCache.put("b","dddd");
logger.info("getById parameter id : {}", id);
Optional<UserHoliday> optional = userHolidayRepository.findById(id);
UserHoliday userHoliday = new UserHoliday();
if (optional.isPresent()) {
userHoliday = optional.get();
}
logger.info("getById return userHoliday:{}", userHoliday);
return userHoliday;
}
/**
* 将满足条件的数据存放到缓存中。
*
* @param id
* @return
* @Cacheable 有一个参数叫做condition,该条件为true时则放到缓存到。该参数同样需使用SpEL表达式。
*/
@Cacheable(value = "test", key = "#id", condition = "#id.equals('2')")
@Override
public UserHoliday getByConditionalId(String id) {
logger.info(" syncCache.getIfPresent : {}", syncCache.getIfPresent("a"));
ArrayList<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
logger.info(" syncCache.getAllPresent : {}", syncCache.getAllPresent(strings));
logger.info("getByConditionalId parameter id : {}", id);
Optional<UserHoliday> optional = userHolidayRepository.findById(id);
UserHoliday userHoliday = new UserHoliday();
if (optional.isPresent()) {
userHoliday = optional.get();
}
logger.info("getByConditionalId return userHoliday:{}", userHoliday);
return userHoliday;
}