Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐)

下面我将详细讲解 Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐)的攻略。

背景

在 Spring Boot 2.x 版本中,默认使用的是 Caffeine 作为本地缓存框架,而在之前的版本中,默认使用的是 Guava,这是因为,Caffeine 有更好的性能和更多的特性。

步骤

下面是使用 Caffeine 缓存的基本步骤:

添加依赖

首先,我们需要添加以下依赖到我们的 pom.xml 文件中:

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.8.8</version>
</dependency>

创建缓存

接下来,我们需要创建一个缓存对象:

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

public class CacheDemo {

    public static void main(String[] args) {
        Cache<String, String> cache = Caffeine.newBuilder()
                .maximumSize(100)
                .build();

        String key = "foo";
        String value = "bar";
        cache.put(key, value);

        System.out.println(cache.getIfPresent(key));
    }
}

代码解释:

  • 我们使用 Caffeine.newBuilder() 方法来创建一个新的缓存对象;
  • 我们通过 maximumSize(100) 方法限制了最大元素数量为 100;
  • 我们通过 build() 方法来构建最终的缓存对象;
  • 我们使用 put(key, value) 方法将一个键值对存入缓存中;
  • 我们使用 getIfPresent(key) 方法获取指定键的值。

缓存配置

除了基本的配置以外,Caffeine 还提供了很多其他的配置选项,比如过期时间、刷新时间等等。下面是一个使用了一些配置选项的例子:

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

public class CacheDemo {

    public static void main(String[] args) throws Exception {
        Cache<String, String> cache = Caffeine.newBuilder()
                .expireAfterWrite(1, TimeUnit.MINUTES)
                .expireAfterAccess(30, TimeUnit.SECONDS)
                .maximumSize(100)
                .recordStats()
                .build();

        String key = "foo";
        String value = "bar";

        // 缓存未命中时,调用 load 方法获取数据
        Function<String, String> loader = k -> value.toUpperCase();
        String result = cache.get(key, loader);
        System.out.println(result);

        // 等待 2 分钟,超时后缓存被清空,所以这里又会调用 loader() 方法
        Thread.sleep(TimeUnit.MINUTES.toMillis(2));
        result = cache.get(key, loader);
        System.out.println(result);

        // 输出缓存命中统计信息
        System.out.println(cache.stats());
    }
}

代码解释:

  • 我们使用 expireAfterWrite(1, TimeUnit.MINUTES) 方法来配置缓存条目在写入后留在缓存中的时间;
  • 我们使用 expireAfterAccess(30, TimeUnit.SECONDS) 方法来配置缓存条目的访问时间;
  • 我们使用 maximumSize(100) 方法来限制缓存最大元素数量为 100;
  • 我们使用 recordStats() 方法来记录缓存的统计信息;
  • 当从缓存中获取数据时,如果缓存未命中,会调用我们定义的 loader 方法来获取数据;
  • 每次获取数据时,如果数据在缓存中已经过期,则会自动调用 loader 方法来刷新缓存;
  • 我们使用 cache.stats() 方法来获取缓存的统计信息。

示例

下面是一个使用 Caffeine 缓存的 Spring Boot 示例:

添加依赖

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.8.8</version>
</dependency>

缓存配置

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCache helloWorldCache = buildCache("helloWorldCache", 10, 5);

        SimpleCacheManager manager = new SimpleCacheManager();
        manager.setCaches(List.of(helloWorldCache));

        return manager;
    }

    private CaffeineCache buildCache(String name, int maxSize, int expireAfterAccessInMinutes) {
        Cache<Object, Object> cache = Caffeine.newBuilder()
                .maximumSize(maxSize)
                .expireAfterAccess(expireAfterAccessInMinutes, TimeUnit.MINUTES)
                .build();

        return new CaffeineCache(name, cache);
    }
}

代码解释:

  • 我们使用 @EnableCaching 注解开启缓存功能;
  • 我们通过 cacheManager() 方法创建一个缓存管理器;
  • 我们通过 buildCache() 方法创建一个缓存对象;
  • 我们使用 CaffeineCache 类包装我们创建的 cache 对象;
  • 我们根据需要创建多个缓存对象,并将它们存储到 SimpleCacheManager 对象中。

缓存使用

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private CacheManager cacheManager;

    @Cacheable(cacheNames = "helloWorldCache", key = "#userId")
    public String getUserById(String userId) {
        // 假装从数据库中获取数据
        return "User-" + userId;
    }

    public void printCacheStats() {
        Cache cache = cacheManager.getCache("helloWorldCache");
        System.out.println(cache.getNativeCache().stats());
    }
}

代码解释:

  • 我们通过 @Cacheable 注解将一个方法设置为可缓存的;
  • 我们使用 cacheNames 属性指定使用的缓存名称;
  • 我们使用 key 属性指定缓存的键;
  • 当访问带有 @Cacheable 注解的方法时,会首先检查缓存,如果找到了对应的值,则直接返回,否则调用方法获取数据,并将数据存入缓存中;
  • 我们可以使用 cacheManager.getCache("helloWorldCache") 方法获取缓存对象,并使用 cache.getNativeCache().stats() 方法获取缓存的统计信息。

总结

在 Spring Boot 2.x 版本中,我们推荐使用 Caffeine 作为本地缓存框架。使用 Caffeine 缓存,我们可以非常方便地创建、配置和使用缓存对象。同时,Caffeine 还提供了很多实用的特性,比如过期时间、统计信息等等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐) - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • SpringBoot Security密码加盐实例

    下面是关于 “SpringBoot Security密码加盐实例” 的详细攻略。 介绍 Spring Security 是一个强大的身份认证和授权框架,Spring Boot 的集成让我们可以非常方便地搭建安全的应用。但是,如果我们对密码进行单纯的 hash 加密,容易被暴力破解,因此需要加盐(salt)使其更加安全。 盐是在密码加密的时候添加到原始密码中的…

    Java 2023年6月3日
    00
  • java实现十六进制字符unicode与中英文转换示例

    下面是Java实现十六进制字符unicode与中英文转换的完整攻略。 概念介绍 Unicode是计算机科学领域中的一项标准,它对世界上所有的文字进行了编码,包括中文、英文、数字、符号等。其中,每个字符都有唯一的一个Unicode码,用16进制数表示。 Java中,使用\u来表示Unicode编码,比如\u0061代表小写字母”a”。 中英文转换就是把中文转换…

    Java 2023年5月20日
    00
  • Mybatis Plus 增删改查的实现(小白教程)

    MyBatis Plus 是基于 MyBatis 的增强工具,简化了 MyBatis 的使用,提供了很多增强功能。相比于原生 MyBatis,MyBatis Plus 更加易用,使用 MyBatis Plus 可以加快开发效率。本文主要介绍如何使用 MyBatis Plus 进行常见的增删改查操作。 安装 MyBatis Plus 要使用 MyBatis P…

    Java 2023年5月20日
    00
  • 正则表达式的匹配字串引用($1、$2…)

    上季度公司一个需求是要求优化项目接口的返回结果处理方式,原先各Controller直接调用SuperController的结果处理方法,类似这样: return callBackSuccess(data); return callBackSuccess(msg, data); return callBackFilure(AppCode.XXX); // Ap…

    Java 2023年4月17日
    00
  • 什么是线程间通信?

    以下是关于线程间通信的完整使用攻略: 什么是线程间通信? 线程间通信是指多个线程之间通过共享内存或消息传递等方式来实现数据的交换和协调工作的过程。在多线程编程中,线程间通信是非常重要的,可以避免线程之间的竞争和冲突,提高程序的效率和稳定性。 线程间通信的方式 线程间通信主要有以下几种方式: 1. 共享内存 共享内存是指多个线程之间共享同一块内存区域,通过读写…

    Java 2023年5月12日
    00
  • SpringBoot 统一异常处理详解

    让我来详细讲解“SpringBoot 统一异常处理详解”的完整攻略。 1. 异常处理的意义 在我们的应用程序中,异常是不可避免的。这些异常可能是由于用户输入不正确、服务器错误、网络问题等各种原因引起的。当这些异常不被处理时,它们将会导致应用程序无法继续正常运行,严重时甚至会引起系统崩溃。 因此,在我们的应用程序中,为了保证程序的安全性和稳定性,必须对这些异常…

    Java 2023年5月27日
    00
  • win2003 服务器 安全设置 技术实例(比较安全的方法)

    Win2003服务器安全设置技术实例 作为一名运维人员,服务器安全设置是不可或缺的一项工作。下面介绍一些比较安全的 Win2003 服务器的技术实例。 禁用不必要的服务 Win2003 服务器中默认启动多项服务,而其中有些服务并不是所有人都需要的。禁用这些不必要的服务,可以减少服务器的攻击面。在启用服务之前,务必确认该服务是否对服务器的正常运行有必要。 下面…

    Java 2023年6月15日
    00
  • SpringBoot整合数据库访问层的实战

    下面我将详细讲解“SpringBoot整合数据库访问层的实战”的完整攻略。 1. 引言 SpringBoot是一个非常强大的Java Web框架,它内置了大量的优秀组件,使得开发者可以快速构建高效的Java Web应用。而与Web应用密切相关的数据库访问层也是非常重要的,本攻略将介绍如何使用SpringBoot快速整合数据库访问层。 2. 数据库访问层的实现…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部