共计 2768 个字符,预计需要花费 7 分钟才能阅读完成。
Caffeine 简介
Caffeine 是一个高性能,高命中率,低内存占用,near optimal 的本地缓存,简略来说它是 Guava Cache 的优化加强版
依赖
<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> |
开启缓存
@EnableCaching
注解开启应用缓存治理性能
@SpringBootApplication | |
@EnableCaching | |
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args); | |
} | |
} |
注入
形式一
- 新建一个枚举类
public enum Caches {CACHE_ACCESS_TOKEN(10, 7200); | |
/** 最大数量 */ | |
private Integer maxSize; | |
/** 过期工夫 秒 */ | |
private Integer ttl; | |
Caches() {} | |
Caches(Integer maxSize, Integer ttl) { | |
this.maxSize = maxSize; | |
this.ttl = ttl; | |
} | |
public Integer getMaxSize() {return maxSize;} | |
public Integer getTtl() {return ttl;} | |
} |
- 注入到 IOC 容器
/** | |
* 本地缓存 | |
* @return | |
*/ | |
@Bean | |
@Primary | |
public CacheManager cacheManager() {SimpleCacheManager simpleCacheManager = new SimpleCacheManager(); | |
ArrayList<CaffeineCache> caffeineCaches = new ArrayList<>(); | |
for (Caches c : Caches.values()) {caffeineCaches.add(new CaffeineCache(c.name(), | |
Caffeine.newBuilder() | |
.recordStats() | |
.expireAfterWrite(c.getTtl(), TimeUnit.SECONDS) | |
.maximumSize(c.getMaxSize()) | |
.build()) | |
); | |
} | |
simpleCacheManager.setCaches(caffeineCaches); | |
return simpleCacheManager; | |
} |
形式二
@Bean | |
@Primary | |
public CacheManager cacheManager() {CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager(); | |
Caffeine<Object, Object> caffeine = Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.MINUTES); | |
caffeineCacheManager.setCaffeine(caffeine); | |
return caffeineCacheManager; | |
} |
应用
能够应用 spring 提供的 @Cacheable、@CachePut、@CacheEvict 等注解来不便的应用 caffeine 缓存
@Cacheable(cacheNames = "CACHE_ACCESS_TOKEN", key = "#root.methodName") | |
public String getAccessToken(String corpid, String corpsecret) { | |
//todo something... | |
return ""; | |
} |
问题
应用 @Cacheable
缓存不起作用
生效场景
- 在公有办法上加缓存
- 类外部办法调用加缓存
生效起因
Spring cache
的实现原理是基于AOP
的动静代理实现的:即都在办法调用前后去获取办法的名称、参数、返回值,而后依据办法名称、参数生成缓存的 key(自定义的 key 例外),进行缓存。
AOP
不反对对private
公有办法的拦挡,所以也就不反对公有办法上的Spring Cache
注解。
this
调用不是代理对象的调用, 所以AOP
生效,注解生效。
解决办法
- 办法用
public
限定符润饰; - 类外部办法调用加缓存时能够用
SpringContextUtil
获取以后Bean
, 由它来调用
工具类
SpringContextUtil
@Component | |
public class SpringContextUtil implements ApplicationContextAware { | |
public static ApplicationContext applicationContext; | |
public void setApplicationContext(ApplicationContext applicationContext) {SpringContextUtil.applicationContext = applicationContext;} | |
public static Object getBean(String name) {return applicationContext.getBean(name); | |
} | |
public static <T> T getBean(Class<T> clazz) {return applicationContext.getBean(clazz); | |
} | |
public static <T> T getBean(String name, Class<T> clazz) {return applicationContext.getBean(name, clazz); | |
} | |
public static Boolean containsBean(String name) {return applicationContext.containsBean(name); | |
} | |
public static Boolean isSingleton(String name) {return applicationContext.isSingleton(name); | |
} | |
public static Class<? extends Object> getType(String name) {return applicationContext.getType(name); | |
} | |
} |
正文完