
Spring接口缓存实现方案Caffeine和EhCache
1.引入jar包 compile("com.github.ben-manes.caffeine:caffeine:2.8.6") compile("org.springframework.boot:spring-boot-starter-cache") 2.application.properties ##配置ehcache spring.cache.ehcache.config = classpath:/ehcache.xml spring.cache.type = ehcache
##配置caffeine 或者使用下面的配置类也可以。 #spring.cache.cache-names=USER3 #spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=5s #spring.cache.type=caffeine
3.配置文件ehcache
<ehcache updateCheck="false" name="configCache">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
<!-- 配置自定义缓存
maxElementsInMemory:缓存中允许创建的最大对象数
eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,
两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,
如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,
这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
overflowToDisk:内存不足时,是否启用磁盘缓存。
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。-->
<cache name="sysConfigCache2"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="900"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LFU" />
</ehcache>4.配置类caffeine
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Configuration
public class CaffeineConfig {
/**
* 默认的超时时间
*/
@Value("${caching.expire.duration:60}")
private int duration;
@Value("${caching.maximumSize:1000}")
private int maximumSize;
@Value("${caching.initialCapacity:50}")
private int initialCapacity;
@Bean
public CacheManager cacheManager() {
CaffeineCache cache = buildCache("USER2", duration);
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(Arrays.asList(cache));
return manager;
}
private CaffeineCache buildCache(String name, int secondsToExpire) {
return new CaffeineCache(name, Caffeine.newBuilder()
.expireAfterWrite(secondsToExpire, TimeUnit.SECONDS)
.maximumSize(maximumSize)
.initialCapacity(initialCapacity)
.build());
}
}5.caffeine演示
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/caffeine")
@lombok.extern.slf4j.Slf4j
public class CaffeineController {
@Autowired
private CaffeineService caffeineService;
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id) {
long start = System.currentTimeMillis();
log.info("查询开始:" + start);
String res = caffeineService.getUser(id);
long end = System.currentTimeMillis();
log.info("查询结束:" + end);
log.info("查询耗时:" + (end - start));
return res;
}
@GetMapping("/user2/{id}")
public String getUser2(@PathVariable String id) {
long start = System.currentTimeMillis();
log.info("查询开始2:" + start);
String res = caffeineService.getUser2(id);
long end = System.currentTimeMillis();
log.info("查询结束2:" + end);
log.info("查询耗时2:" + (end - start));
return res;
}
@GetMapping("/user/{id}/{name}")
public String updateUser(@PathVariable String id, @PathVariable String name) {
return caffeineService.updateUser(id, name);
}
@DeleteMapping("/user/{id}")
public String delUser(@PathVariable String id) {
return caffeineService.delUser(id);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@lombok.extern.slf4j.Slf4j
@Service
public class CaffeineService {
public static Map<String, String> map = new HashMap<>();
@Autowired
CacheManager cacheManager;
static {
map.put("1", "zhangsan");
map.put("2", "lisi");
map.put("3", "wangwu");
}
@Cacheable(value = "USER3", key = "#id")
public String getUser(String id) {
System.out.println("getUser() run......");
log.info("getUser() run......");
// 这是在使用注解时做的调试,每次都进来这里,说明缓存没有生效。
if (null != cacheManager.getCache("USER3").get(id)) {
Object common = cacheManager.getCache("USER3").get(id).get();
log.warn("cache !!!============ {}", common);
System.out.println("cache !!!============");
} else {
log.warn("no cache !!!============");
System.out.println("no cache !!!============");
}
return map.get(id);
}
/**
* 手动写, 更加有优势,注解方式的话,如果key删除了,就没有返回数据,不会重新从数据库中获取初始化。
* @param id
* @return
*/
public String getUser2(String id) {
System.out.println("getUser() run......");
String cacheKey = id;
Cache cache = cacheManager.getCache("USER3");
String user = (String) Optional.ofNullable(cache)
.map(c -> c.get(cacheKey))
.map(wapper -> {
Object o = wapper.get();
System.out.println("fetch.................");
log.info("fetch user from cache: cacheKey: {}, String: {}", cacheKey, o);
return o;
}).orElseGet(() -> {
String response = map.get(id);
return Optional.ofNullable(response)
.map(data -> {
cache.put(cacheKey, data);
log.info("put init user from cache: id: {}, String: {}", cacheKey, data);
System.out.println("put init .................");
return data;
}).orElse(null);
});
return user;
}
@CachePut(value = "USER3", key = "#id")
public String updateUser(String id, String name) {
log.info("updateUser() run......");
map.put(id, name);
return map.get(id);
}
@CacheEvict(value = "USER3", key = "#id")
public String delUser(String id) {
log.info("delUser() run......");
map.remove(id);
return map.toString();
}
}访问 #查询 http://localhost:8080/caffeine/user/1 #查询2 http://localhost:8080/caffeine/user2/1 #修改 http://localhost:8080/caffeine/user/1/simayi #删除 http://localhost:8080/caffeine/user/1
6.ehcache演示
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/ehcache")
@lombok.extern.slf4j.Slf4j
public class EhCacheController {
@Autowired
private EhCacheService ehCacheService;
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id) {
long start = System.currentTimeMillis();
log.info("查询开始:" + start);
String res = ehCacheService.getUser(id);
long end = System.currentTimeMillis();
log.info("查询结束:" + end);
log.info("查询耗时:" + (end - start));
return res;
}
@GetMapping("/user2/{id}")
public String getUser2(@PathVariable String id) {
long start = System.currentTimeMillis();
log.info("查询开始2:" + start);
String res = ehCacheService.getUser2(id);
long end = System.currentTimeMillis();
log.info("查询结束2:" + end);
log.info("查询耗时2:" + (end - start));
return res;
}
@GetMapping("/user/{id}/{name}")
public String updateUser(@PathVariable String id, @PathVariable String name) {
return ehCacheService.updateUser(id, name);
}
@DeleteMapping("/user/{id}")
public String delUser(@PathVariable String id) {
return ehCacheService.delUser(id);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@lombok.extern.slf4j.Slf4j
@Service
public class EhCacheService {
public static Map<String, String> map = new HashMap<>();
@Autowired
CacheManager cacheManager;
static {
map.put("1", "zhangsan22");
map.put("2", "lisi22");
map.put("3", "wangwu22");
}
@Cacheable(value = "sysConfigCache2", key = "#id")
public String getUser(String id) {
System.out.println("getUser() run......");
log.info("getUser() run......");
// 这是在使用注解时做的调试,每次都进来这里,说明缓存没有生效。
if (null != cacheManager.getCache("sysConfigCache2").get(id)) {
Object common = cacheManager.getCache("sysConfigCache2").get(id).get();
log.info("cache !!!============ {}", common);
System.out.println("cache !!!============");
} else {
log.warn("no cache !!!============");
System.out.println("no cache !!!============");
}
return map.get(id);
}
/**
* 手动写, 更加有优势,注解方式的话,如果key删除了,就没有返回数据,不会重新从数据库中获取初始化。
* @param id
* @return
*/
public String getUser2(String id) {
System.out.println("getUser() run......");
String cacheKey = id;
Cache cache = cacheManager.getCache("sysConfigCache2");
String user = (String) Optional.ofNullable(cache)
.map(c -> c.get(cacheKey))
.map(wapper -> {
Object o = wapper.get();
System.out.println("fetch.................");
log.info("fetch user from cache: cacheKey: {}, String: {}", cacheKey, o);
return o;
}).orElseGet(() -> {
String response = map.get(id);
return Optional.ofNullable(response)
.map(data -> {
cache.put(cacheKey, data);
log.info("put init user from cache: id: {}, String: {}", cacheKey, data);
System.out.println("put init .................");
return data;
}).orElse(null);
});
return user;
}
@CachePut(value = "sysConfigCache2", key = "#id")
public String updateUser(String id, String name) {
log.info("updateUser() run......");
map.put(id, name);
return map.get(id);
}
@CacheEvict(value = "sysConfigCache2", key = "#id")
public String delUser(String id) {
log.info("delUser() run......");
map.remove(id);
return map.toString();
}
}访问 #查询 http://localhost:8080/ehcache/user/1 #查询2 http://localhost:8080/ehcache/user2/1 #修改 http://localhost:8080/ehcache/user/1/zhugeliang #删除 http://localhost:8080/ehcache/user/1