guava本地缓存应用
我的应用场景是模糊查询框
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import com.kevin.demo.pojo.DeveloperCache;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class LocalCacheDemo {
@Value("${developer.caches.initial-capacity:3000}")
private Integer initialCapacity;
@Value("${developer.caches.concurrency-level:16}")
private Integer concurrencyLevel;
@Value("${developer.caches.maximum-size:30000}")
private Integer maximumSize;
@Value("${developer.caches.entry-timeout:60}")
private Integer entryTimeout;
private LoadingCache<String, List<DeveloperCache>> derpSynResps;
private LoadingCache<String, List<DeveloperCache>> noDerpSynResps;
@PostConstruct
void initialize() {
// derp异步信息
derpSynRespsInit();
// derp未异步信息
noDerpSynRespsInit();
}
private void derpSynRespsInit() {
derpSynResps = CacheBuilder.newBuilder()
// 初始容量
.initialCapacity(initialCapacity)
// 并发级别
.concurrencyLevel(concurrencyLevel)
// 最大size
.maximumSize(maximumSize)
// 当缓存项上一次更新操作之后的多久会被刷新
.refreshAfterWrite(entryTimeout, TimeUnit.SECONDS)
.build(new CacheLoader<String, List<DeveloperCache>>() {
@Override
public List<DeveloperCache> load(String unused) throws Exception {
List<DeveloperCache> developerCacheList = derpStateMapper.queryNameAndPhone();
developerCacheList.forEach(temp -> {
if (!StringUtils.isEmpty(temp.getFullName())) {
// 解密
temp.setFullName(AESUtils.decrypt(temp.getFullName()));
}
});
return developerCacheList;
}
@Override
public ListenableFuture<List<DeveloperCache>> reload(String key, List<DeveloperCache> oldValue)
throws Exception {
return super.reload(key, oldValue);
}
});
}
private void noDerpSynRespsInit() {
noDerpSynResps = CacheBuilder.newBuilder()
.initialCapacity(initialCapacity)
.concurrencyLevel(concurrencyLevel)
.maximumSize(maximumSize)
.refreshAfterWrite(entryTimeout, TimeUnit.SECONDS)
.build(new CacheLoader<String, List<DeveloperCache>>() {
@Override
public List<DeveloperCache> load(String unused) throws Exception {
List<DeveloperCache> developerCacheList = developerMapper.queryNameAndPhone();
developerCacheList.forEach(temp -> {
if (!StringUtils.isEmpty(temp.getFullName())) {
temp.setFullName(AESUtils.decrypt(temp.getFullName()));
}
if (!StringUtils.isEmpty(temp.getContactEmail())) {
temp.setContactEmail(AESUtils.decrypt(temp.getContactEmail()));
}
if (!StringUtils.isEmpty(temp.getContactPhoneNum())) {
temp.setContactPhoneNum(AESUtils.decrypt(temp.getContactPhoneNum()));
}
});
return developerCacheList;
}
@Override
public ListenableFuture<List<DeveloperCache>> reload(String key, List<DeveloperCache> oldValue)
throws Exception {
return super.reload(key, oldValue);
}
});
}
@SneakyThrows
private void getDeveloperList() {
List<DeveloperCache> derpSynRespsList;
derpSynRespsList = derpSynResps.get("");
// TODO
}
}
springboot自带的缓存:存储一些简单的数据结构。
只有在触发@CacheEvict(cacheNames = {DICT_LIST, DICT_VALUE}, allEntries = true)
才会更新缓存
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictDao, SysDict> implements SysDictService {
@Autowired
private SysDictDao sysDictDao;
private static final String DICT_LIST = "dict:list";
private static final String DICT_VALUE = "dict:value";
@Override
@Cacheable(cacheNames = DICT_LIST, key = "#code")
public List<SysDict> getList(String code) {
return sysDictDao.getList(code);
}
@Override
@Cacheable(cacheNames = DICT_VALUE, key = "#code+'_'+#dictKey")
public String getValue(String code, Integer dictKey) {
return sysDictDao.getValue(code, dictKey);
}
@Override
@CacheEvict(cacheNames = {DICT_LIST, DICT_VALUE}, allEntries = true)
public void remove(List<Integer> ids) {
ids.forEach(id -> sysDictDao.deleteById(id));
}
@Override
@CacheEvict(cacheNames = {DICT_LIST, DICT_VALUE}, allEntries = true)
public void addOrUpdate(SysDict sysDict) {
Integer count = sysDictDao.getCount(sysDict.getCode(), sysDict.getDictKey());
if (count > 0) {
throw new ServiceException("当前字典键值已存在!");
} else {
saveOrUpdate(sysDict);
}
}
}
想深入了解可参考: