SpringBoot使用caffeine本地缓存

SpringBoot使用caffeine本地缓存

caffeine介绍

Caffeine 是基于 JAVA 8 的高性能缓存库。并且在 spring5 (springboot 2.x) 后,spring 官方放弃了 Guava,而使用了性能更优秀的 Caffeine 作为默认缓存组件。

使用 Caffeine 方法实现缓存

1、引入caffeine依赖pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

2、本地缓存配置类CacheConfig

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;

/**
 * title CacheConfig
 * Description 本地缓存配置类
 * CreateDate 2022/3/7 13:45
 *
 * @author izhouy
 */
@Configuration
public class CacheConfig {

    @Bean
    public Cache caffeineCache() {
        return Caffeine.newBuilder()
                // 设置最后一次写入或访问后经过固定时间过期
                .expireAfterWrite(60, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(1000)
                .build();
    }

}

3、控制层接口

@RestController
@RequestMapping("/interlib")
public class InterlibController {

    @Autowired
    Cache<String, Object> caffeineCache;

    /**
     * 加入缓存
     * @return
     */
    @GetMapping("/setSession/{id}")
    public String setSession(@PathVariable String id) {
        log.info("create");
        // 加入缓存(key不存在则新增,存在则更新)
        caffeineCache.put(id, "13123123");
        return "success"
    }
    
    /**
     * 获取缓存
     * @return
     */
    @GetMapping("/getSession/{id}")
    public String getSessionId(@PathVariable String id) {
        log.info("get");
        // 获取缓存
        caffeineCache.getIfPresent(id);
        return (String)caffeineCache.asMap().get(id);
    }
}

使用 SpringCache 注解方法实现缓存

1、引入caffeine依赖pom

        <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>

2、本地缓存配置类CacheConfig

package info.jiatu.htlsp.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;

/**
 * title CacheConfig
 * Description 本地缓存配置类
 * CreateDate 2022/3/7 13:45
 *
 * @author izhouy
 */
@Configuration
public class CacheConfig {

    /**
     * 配置缓存管理器
     * @return 缓存管理器
     */
    @Bean("caffeineCacheManager")
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
                // 最后一次写入后经过固定时间过期300秒
                .expireAfterWrite(300, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(1000));
        return cacheManager;
    }
}

3、在需要缓存的类和方法上添加@EnableCaching和@Cacheable

接口类InterlibService
/**
 * title InterlibService
 * Description interlib接口调用处理
 * CreateDate 2022/3/2 11:17
 *
 * @author izhouy
 */
public interface InterlibService {

    /**
     * 获取interlib的SessionId
     * @return
     */
    Result<String> getSessionId();
}
实现类InterlibServiceImpl
@Service("interlibService")
@Slf4j
@EnableCaching
public class InterlibServiceImpl implements InterlibService {

    @Override
    @Cacheable(cacheNames = "caffeineCacheManager", key = "#root.targetClass.simpleName+'-getSessionId'", unless = "!#result.success")
    public Result<String> getSessionId() {
    	System.out.println("获取数据");
    	return new Result(200, "查询成功", "12321312");
    }
}

4、统一响应实体类Result

package info.jiatu.htlsp.entity.response;

import org.apache.commons.lang3.StringUtils;

/**
 * 统一API响应结果封装
 *
 * @author admin
 */
public class Result<T> {
    /**
     * 响应编号,参考ResultCode
     */
    private int code;
    /**
     * 消息
     */
    private String message;
    /**
     * 数据
     */
    private T data;

    private Boolean success;
    
    public Result(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
        this.success = isSuccess();
    }
    public boolean isSuccess() {
        return this.code == 200;
    }
}

5、控制层接口

@RestController
@RequestMapping("/interlib")
public class InterlibController {

    @Autowired
    private InterlibService interlibService;

    /**
     * 获取interlib的SessionId信息
     * @return
     */
    @GetMapping("/getSession")
    public Result<String> getSessionId() {
        return interlibService.getSessionId();
    }
}

caffeine配置说明

参数类型描述
initialCapacityint初始的缓存空间大小
maximumSizelong缓存的最大条数
maximumWeightlong缓存的最大权重
expireAfterWrite或expireAfterAccessduration最后一次写入或访问后经过固定时间过期
refreshAfterWriteduration最后一次写入后经过固定时间过期
refreshAfterWriteduration创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存
weakKeysboolean打开 key 的弱引用
weakValuesboolean打开 value 的弱引用
softValuesboolean打开 value 的软引用
recordStats开发统计功能

备注:

  • weakValuessoftValues 不可以同时使用。
  • maximumSizemaximumWeight 不可以同时使用。
  • expireAfterWriteexpireAfterAccess 同事存在时,以 expireAfterWrite 为准。

注解说明

注解说明
@Cacheable主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CachePut主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachEvict主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheConfig所有的@Cacheable()里面都有一个value=“xxx”的属性,CacheConfig主要针对类配置,如果你在你的方法写别的名字,那么依然以方法的名字为准。
@EnableCaching注解是spring framework中的注解驱动的缓存管理功能。自spring版本3.1起加入了该注解。如果你使用了这个注解,那么你就不需要在XML文件中配置cache manager了。可以加在启动类上,也可以加在配置类上,还可以加在缓存实现类上。主要加在启动类上。
@Caching有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。
@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
public User save(User user) {
}

自定义缓存注解

之前的那个@Caching组合,会让方法上的注解显得整个代码比较乱,此时可以使用自定义注解把这些注解组合到一个注解中,如:

@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}

这样我们在方法上使用如下代码即可,整个代码显得比较干净。

@UserSaveCache
public User save(User user)

注解参数

参数名说明
value缓存的名称,在 spring 配置文件中定义,必须指定至少一个
key缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
condition缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
unless缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 false 才进行缓存
cacheNames指定配置
allEntries是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
beforeInvocation是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存

SpEL上下文数据

名称位置描述示例
methodNameroot对象当前被调用的方法名root.methodName
methodroot对象当前被调用的方法root.method.name
targetroot对象当前被调用的目标对象root.target
targetClassroot对象当前被调用的目标对象类root.targetClass
argsroot对象当前被调用的方法的参数列表root.args[0]
cachesroot对象当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cacheroot.caches[0].name
argument name执行上下文当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数user.id
result执行上下文方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache evict’的beforeInvocation=false)result
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值