使用本地缓存的目的是加快数据读取速度,减少对数据库的访问,降低数据库压力。本地缓存是直接从本地内存中读取数据,没有网络开销。不同与Redis,Redis能够很好的作为分布式缓存组件提供多个服务间的缓存,但是Redis还是需要网络开销,增加了时耗。
此处记录Caffeine的使用,关于Caffeine的使用有多种方式,例如在SpringBoot中单纯的使用Caffeine,还有Caffeine与spring-boot-starter-cache结合的实现方式,以及Caffeine、Guaua、spring-boot-starter-cache的实现方式等多种方式。
一、添加依赖
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.9.3</version>
</dependency>
二、书写配置类
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("apiCacheManager")
public Cache<String, Object> cacheManager() {
return Caffeine.newBuilder()
.expireAfterAccess(60, TimeUnit.SECONDS)
.initialCapacity(100)
.maximumSize(1000)
.build();
}
}
关于Caffeine的配置说明如下所示
弱引用与软引用
弱引用:弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
Caffeine.newBuilder().weakKeys().weakValues().build();
软引用 :如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
Caffeine.newBuilder().softValues().build();
三、书写缓存接口
在使用缓存的时候,需要注意的是:1、此处直接使用的是Caffeine,不是使用注解的方式;2、@CacheConfig加载的是上一步定义好的bean
import com.github.benmanes.caffeine.cache.Cache;
import com.smile.transport.mapper.TokenMapper;
import com.smile.transport.model.ApiBaseModel;
import com.smile.transport.service.ApiCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@CacheConfig(cacheNames = "apiCacheManager")
public class ApiCacheServiceImpl implements ApiCacheService {
//数据库操作层
@Autowired
private TokenMapper tokenMapper;
@Autowired
private Cache<String, Object> caffeineCache;
//新增缓存
@Override
public void addApiInfo(ApiBaseModel apiBaseModel) {
caffeineCache.put(apiBaseModel.getId(), apiBaseModel);
}
//获取缓存数据
@Override
public ApiBaseModel getAccount() {
//先从缓存中查询数据
ApiBaseModel apiBaseModel = (ApiBaseModel) caffeineCache.asMap().get("api_account");
if (apiBaseModel != null) {
return apiBaseModel;
}
//如果缓存中不存在,则从库中查询
apiBaseModel = this.tokenMapper.selectAccount();
//如果账号信息不为空,则加入缓存
if (apiBaseModel != null) {
caffeineCache.put(apiBaseModel.getId(), apiBaseModel);
}
return apiBaseModel;
}
//更新缓存
@Override
public ApiBaseModel updateAccount(ApiBaseModel apiBaseModel) {
log.info("update");
//此处没有写具体的更新流程,可以根据自己实际需要编写
return apiBaseModel;
}
//删除缓存
@Override
public void deleteAccount(String id) {
log.info("delete");
caffeineCache.asMap().remove(id);
}
}
四、使用
Controller层调用service层接口,实现具体方法即可