你还在用Guava Cache?它才是Java本地缓存之王,java校招面试问题大全及答案大全

「5. 统计」

与Guava Cache的统计一样。

Cache<String, Object> cache = Caffeine.newBuilder()

.maximumSize(10_000)

.recordStats()

.build();

通过使用Caffeine.recordStats(), 可以转化成一个统计的集合. 通过 Cache.stats() 返回一个CacheStats。CacheStats提供以下统计方法:

  • hitRate(): 返回缓存命中率

  • evictionCount(): 缓存回收数量

  • averageLoadPenalty(): 加载新值的平均时间

SpringBoot 中默认Cache-Caffine Cache

SpringBoot 1.x版本中的默认本地cache是Guava Cache。在2.x(Spring Boot 2.0(spring 5) )版本中已经用Caffine Cache取代了Guava Cache。毕竟有了更优的缓存淘汰策略。

下面我们来说在SpringBoot2.x版本中如何使用cache。

引入依赖:

org.springframework.boot

spring-boot-starter-cache

com.github.ben-manes.caffeine

caffeine

2.6.2

添加注解开启缓存支持

添加@EnableCaching注解:

@SpringBootApplication

@EnableCaching

public class SingleDatabaseApplication {

public static void main(String[] args) {

SpringApplication.run(SingleDatabaseApplication.class, args);

}

}

配置文件的方式注入相关参数

properties文件

spring.cache.cache-names=cache1

spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10s

或Yaml文件

spring:

cache:

type: caffeine

cache-names:

  • userCache

caffeine:

spec: maximumSize=1024,refreshAfterWrite=60s

如果使用refreshAfterWrite配置,必须指定一个CacheLoader.不用该配置则无需这个bean,如上所述,该CacheLoader将关联被该缓存管理器管理的所有缓存,所以必须定义为CacheLoader<Object, Object>,自动配置将忽略所有泛型类型。

import com.github.benmanes.caffeine.cache.CacheLoader;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

  • @author: rickiyang

  • @date: 2019/6/15

  • @description:

*/

@Configuration

public class CacheConfig {

/**

  • 相当于在构建LoadingCache对象的时候 build()方法中指定过期之后的加载策略方法

  • 必须要指定这个Bean,refreshAfterWrite=60s属性才生效

  • @return

*/

@Bean

public CacheLoader<String, Object> cacheLoader() {

CacheLoader<String, Object> cacheLoader = new CacheLoader<String, Object>() {

@Override

public Object load(String key) throws Exception {

return null;

}

// 重写这个方法将oldValue值返回回去,进而刷新缓存

@Override

public Object reload(String key, Object oldValue) throws Exception {

return oldValue;

}

};

return cacheLoader;

}

}

Caffeine常用配置说明:

  • initialCapacity=[integer]: 初始的缓存空间大小

  • maximumSize=[long]: 缓存的最大条数

  • maximumWeight=[long]: 缓存的最大权重

  • expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期

  • expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期

  • refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存

  • weakKeys: 打开key的弱引用

  • weakValues:打开value的弱引用

  • softValues:打开value的软引用

  • recordStats:开发统计功能

注意:

  • expireAfterWrite和expireAfterAccess同时存在时,以expireAfterWrite为准。

  • maximumSize和maximumWeight不可以同时使用

  • weakValues和softValues不可以同时使用

需要说明的是,使用配置文件的方式来进行缓存项配置,一般情况能满足使用需求,但是灵活性不是很高,如果我们有很多缓存项的情况下写起来会导致配置文件很长。所以一般情况下你也可以选择使用bean的方式来初始化Cache实例。

下面的演示使用bean的方式来注入:

package com.rickiyang.learn.cache;

import com.github.benmanes.caffeine.cache.CacheLoader;

import com.github.benmanes.caffeine.cache.Caffeine;

import org.apache.commons.compress.utils.Lists;

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 org.springframework.context.annotation.Primary;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.TimeUnit;

/**

  • @author: rickiyang

  • @date: 2019/6/15

  • @description:

*/

@Configuration

public class CacheConfig {

/**

  • 创建基于Caffeine的Cache Manager

  • 初始化一些key存入

  • @return

*/

@Bean

@Primary

public CacheManager caffeineCacheManager() {

SimpleCacheManager cacheManager = new SimpleCacheManager();

ArrayList caches = Lists.newArrayList();

List list = setCacheBean();

for(CacheBean cacheBean : list){

caches.add(new CaffeineCache(cacheBean.getKey(),

Caffeine.newBuilder().recordStats()

.expireAfterWrite(cacheBean.getTtl(), TimeUnit.SECONDS)

.maximumSize(cacheBean.getMaximumSize())

.build()));

}

cacheManager.setCaches(caches);

return cacheManager;

}

/**

  • 初始化一些缓存的 key

  • @return

*/

private List setCacheBean(){

List list = Lists.newArrayList();

CacheBean userCache = new CacheBean();

userCache.setKey(“userCache”);

userCache.setTtl(60);

userCache.setMaximumSize(10000);

CacheBean deptCache = new CacheBean();

deptCache.setKey(“userCache”);

deptCache.setTtl(60);

deptCache.setMaximumSize(10000);

list.add(userCache);

list.add(deptCache);

return list;

}

class CacheBean {

private String key;

private long ttl;

private long maximumSize;

public String getKey() {

return key;

}

public void setKey(String key) {

this.key = key;

}

public long getTtl() {

return ttl;

}

public void setTtl(long ttl) {

this.ttl = ttl;

}

public long getMaximumSize() {

return maximumSize;

}

public void setMaximumSize(long maximumSize) {

this.maximumSize = maximumSize;

}

}

}

创建了一个SimpleCacheManager作为Cache的管理对象,然后初始化了两个Cache对象,分别存储user,dept类型的缓存。当然构建Cache的参数设置我写的比较简单,你在使用的时候酌情根据需要配置参数。

使用注解来对 cache 增删改查

我们可以使用spring提供的 @Cacheable、@CachePut、@CacheEvict等注解来方便的使用caffeine缓存。

如果使用了多个cahce,比如redis、caffeine等,必须指定某一个CacheManage为@primary,在@Cacheable注解中没指定 cacheManager 则使用标记为primary的那个。

cache方面的注解主要有以下5个:

  • @Cacheable 触发缓存入口(这里一般放在创建和获取的方法上,@Cacheable注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存)

  • @CacheEvict 触发缓存的eviction(用于删除的方法上)

  • @CachePut 更新缓存且不影响方法执行(用于修改的方法上,该注解下的方法始终会被执行)

  • @Caching 将多个缓存组合在一个方法上(该注解可以允许一个方法同时设置多个注解)

  • @CacheConfig 在类级别设置一些缓存相关的共同配置(与其它缓存配合使用)

说一下@Cacheable 和 @CachePut的区别:

  • @Cacheable:它的注解的方法是否被执行取决于Cacheable中的条件,方法很多时候都可能不被执行。

  • @CachePut:这个注解不会影响方法的执行,也就是说无论它配置的条件是什么,方法都会被执行,更多的时候是被用到修改上。

简要说一下Cacheable类中各个方法的使用:

public @interface Cacheable {

/**

  • 要使用的cache的名字

*/

@AliasFor(“cacheNames”)

String[] value() default {};

/**

  • 同value(),决定要使用那个/些缓存

*/

@AliasFor(“value”)

String[] cacheNames() default {};

/**

  • 使用SpEL表达式来设定缓存的key,如果不设置默认方法上所有参数都会作为key的一部分

*/

String key() default “”;

/**

  • 用来生成key,与key()不可以共用

*/

String keyGenerator() default “”;

/**

  • 设定要使用的cacheManager,必须先设置好cacheManager的bean,这是使用该bean的名字

*/

String cacheManager() default “”;

/**

  • 使用cacheResolver来设定使用的缓存,用法同cacheManager,但是与cacheManager不可以同时使用

*/

String cacheResolver() default “”;

/**

  • 使用SpEL表达式设定出发缓存的条件,在方法执行前生效

*/

String condition() default “”;

/**

  • 使用SpEL设置出发缓存的条件,这里是方法执行完生效,所以条件中可以有方法执行后的value

*/

String unless() default “”;

/**

  • 用于同步的,在缓存失效(过期不存在等各种原因)的时候,如果多个线程同时访问被标注的方法

  • 则只允许一个线程通过去执行方法

*/

boolean sync() default false;

}

基于注解的使用方法:

package com.rickiyang.learn.cache;

import com.rickiyang.learn.entity.User;

import org.springframework.cache.annotation.CacheEvict;

import org.springframework.cache.annotation.CachePut;

import org.springframework.cache.annotation.Cacheable;

import org.springframework.stereotype.Service;

/**

  • @author: rickiyang

  • @date: 2019/6/15

  • @description: 本地cache

*/

@Service

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例

MyBatis答案解析
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!*

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-P2ZUpWwY-1711098854672)]
[外链图片转存中…(img-4uOwQOPs-1711098854672)]
[外链图片转存中…(img-k7pJBne4-1711098854673)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-AHYht3Np-1711098854673)]

最后

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例
[外链图片转存中…(img-cGmMSM4W-1711098854673)]

[外链图片转存中…(img-HF4cryq8-1711098854673)]
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 24
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值