首页 > 其他分享 >JCache 介绍

JCache 介绍

时间:2024-03-17 19:34:56浏览次数:12  
标签:JCache 缓存 Cache 介绍 cache key import myCache

JCache 是 Java 官方的缓存规范即 JSR107,主要明确了Java 中基于内存进行对象缓存的一些要求,涵盖对象的创建、查询、更新、删除、一致性保证等方面内容;本文主要介绍其基本概念及简单使用。

1、JCache 简介

1.1、核心概念

JCache 中定义了五个核心接口:CachingProvider、CacheManager、Cache、Entry 和 ExpiryPolicy。

A、CachingProvider 用于创建、配置、获取、管理和控制零个或多个 CacheManager;应用程序在运行时可以访问或使用零个或多个 CachingProvider。
B、CacheManager 用于创建、配置、获取、管理和控制零个或多个唯一命名的 Cache,这些 Cache 存在于 CacheManager 的上下文中;一个 CacheManager 只能归属一个 CachingProvider。
C、Cache 是类似 Map 的数据结构,用于临时存储基于 key 的 value;一个 Cache 只能归属一个 CacheManager。
D、Entry 是存储在 Cache 中的键值对。
E、ExpiryPolicy 定义了每个 Entry 在 Cache 中有效时间(TTL),有效期内 Entry 能够被访问、修改和删除,有效期后该 Entry 不能在被访问、修改和删除。

对应关系如下:

1.2、相关注解

JSR107 将一些常用的 API 方法封装为注解,利用注解来简化编码的复杂度,降低缓存对于业务逻辑的侵入性,使得业务开发人员更加专注于业务本身的开发。

注解说明
@CacheResult 将指定的 key 和 value 存入到缓存容器中
@CachePut 更新缓存容器中对应 key 的缓存内容
@CacheRemove 移除缓存容器中对应 key 的缓存记录
@CacheRemoveAll 移除缓存容器中的所有缓存记录
@CacheKey 指定缓存的 key,用于方法参数前面
@CacheValue 指定缓存的 value,用于方法参数前面
上述注解主要是添加在方法上面,用于自动将方法的入参与返回结果之间进行一个映射与自动缓存,对于后续请求如果命中缓存则直接返回缓存结果而无需再次执行方法的具体处理,以此来提升接口的响应速度与承压能力。

1.3、值存储和引用存储

JSR-107 中定义了两种存储 Entry 的方法,即按值存储(Store-By-Value)和按引用存储(Store-By-Reference)。
• 按值存储是默认机制,也就是在存储键值对时,先对 key 和 value 进行拷贝,然后将拷贝的副本存储到 Cache 中;当访问 Cache 时,返回的是数据的副本。
• 按引用存储是另外一种可选的机制,存储键值对时,Cache 中存储的是 key 和 value 的引用。当应用程序修改键值对时,应用程序无需再次修改 Cache 中的数据。

1.4、一致性

一致性是指当并发访问缓存时,需要保证修改的可见性在并发线程/进程间是一致的。为了保证一致性,所有的实现框架都应该支持默认一致性模型:

在执行大部分 Cache 操作时,就好像为 Cache 中的每个 key 加了锁,当某个操作获取该 key 的排它性读写锁时,后面对该 key 的所有操作都会被阻塞,直到这个锁释放。注意,这里的操作可以是单个 JVM 进程内的,也可以是跨 JVM 的操作。对于某些具有返回值的 Cache 操作,返回的缓存值需要是最新值。但是这个最新值,可以根据缓存的具体实现定义,比如当并发修改时,这个返回值可以是修改前的值,也可以是修改后的值。

1.5、Cache 和 Map 的差异

相同点:

  • 都是通过 key 进行存储和访问。
  • 每个 key 都与一个 value 对应。
  • 当使用可变对象作为 key 时,修改 key 值可能导致获取不到 key 对应的 value。
  • 使用自定义类作为 key 时,需要覆盖 Object.equals() 和 Object.hashCode() 方法。

不同点:

  • Cache 的 key 和 value 不许为 null,如果设置了 null,则会抛出 NullPointerException。
  • Cache 中的 Entry 可能会过期(Expire)。
  • Cache 中的 Entry 可能被驱逐(Evicted)。
  • 为了支持原子比较和交换(compare-and-swap, CAP),Cache 中的自定义 key 应覆盖 Object.equals() 和 Object.hashCode() 方法。
  • Cache 中的 key 和 value 是需要可被序列化的。
  • Cache 可以设置使用值存储或引用存储来存储 Entry。
  • Cache 可以选择强制的安全性限制,如果违规操作,可以抛出 SecurityException 异常。

2、JCache 使用

JCache 只是定义了一组接口,要使用还需引入具体的实现框架。

2.1、Caffeine 中使用 JCache

2.1.1、引入依赖

<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>jcache</artifactId>
    <version>2.9.3</version>
</dependency>

2.1.2、简单使用

@Test
public void caffeine() {
    CachingProvider cachingProvider = Caching.getCachingProvider("com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider");
    CacheManager cacheManager = cachingProvider.getCacheManager();
    MutableConfiguration<Integer, String> mutableConfiguration = new MutableConfiguration<Integer, String>()
            .setTypes(Integer.class, String.class)
            .setStoreByValue(false)
            .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 5)));
    Cache<Integer, String> myCache = cacheManager.createCache("myCache", mutableConfiguration);
    myCache.put(1, "aaa");
    log.info(myCache.get(1));
    cacheManager.close();
}

2.2、Ehcache3 中使用 JCache

2.2.1、引入依赖

<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.10.8</version>
    <exclusions>
        <exclusion>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2.2.2、简单使用

@Test
public void ehcache3() {
    CachingProvider cachingProvider = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
    CacheManager cacheManager = cachingProvider.getCacheManager();
    MutableConfiguration<Integer, String> mutableConfiguration = new MutableConfiguration<Integer, String>()
            .setTypes(Integer.class, String.class)
            .setStoreByValue(false)
            .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 5)));
    Cache<Integer, String> myCache = cacheManager.createCache("myCache", mutableConfiguration);
    log.info(myCache.getClass().getName() + "|" + myCache.getClass().getCanonicalName());
    myCache.put(1, "aaa");
    log.info(myCache.get(1));
    cacheManager.close();
}

 Caffeine 及 Ehcache3 中使用 JCache 的完整代码:

package com.abc.demo.cache;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import javax.cache.spi.CachingProvider;
import java.util.concurrent.TimeUnit;

@Slf4j
public class JCacheCase {
    @Test
    public void caffeine() {
        CachingProvider cachingProvider = Caching.getCachingProvider("com.github.benmanes.caffeine.jcache.spi.CaffeineCachingProvider");
        CacheManager cacheManager = cachingProvider.getCacheManager();
        MutableConfiguration<Integer, String> mutableConfiguration = new MutableConfiguration<Integer, String>()
                .setTypes(Integer.class, String.class)
                .setStoreByValue(false)
                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 5)));
        Cache<Integer, String> myCache = cacheManager.createCache("myCache", mutableConfiguration);
        myCache.put(1, "aaa");
        log.info(myCache.get(1));
        cacheManager.close();
    }

    @Test
    public void ehcache3() {
        CachingProvider cachingProvider = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
        CacheManager cacheManager = cachingProvider.getCacheManager();
        MutableConfiguration<Integer, String> mutableConfiguration = new MutableConfiguration<Integer, String>()
                .setTypes(Integer.class, String.class)
                .setStoreByValue(false)
                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 5)));
        Cache<Integer, String> myCache = cacheManager.createCache("myCache", mutableConfiguration);
        log.info(myCache.getClass().getName() + "|" + myCache.getClass().getCanonicalName());
        myCache.put(1, "aaa");
        log.info(myCache.get(1));
        cacheManager.close();
    }
}
JCacheCase.java

2.3、SpringBoot 中 JCache 注解使用

2.3.1、引入依赖

这里使用 Caffeine 作为 JCache 的实现框架。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
    <relativePath />
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>jcache</artifactId>
    </dependency>
</dependencies>

2.3.2、配置缓存名称

spring:
  cache:
    type: jcache
    cacheNames: myCache

2.3.3、启用缓存

启动类上增加 @EnableCaching 注解。

@SpringBootApplication
@EnableCaching
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

2.3.4、JCache 注解使用

package com.abc.general.service.impl;

import com.abc.general.service.ICacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.cache.annotation.*;

@Slf4j
@Service
public class CacheServiceImpl implements ICacheService {
    @CacheResult(cacheName = "myCache")
    @Override
    public String queryById(@CacheKey int id) {
        log.info("queryById,id={}", id);
        return "value" + id;
    }

    @CachePut(cacheName = "myCache")
    @Override
    public String updateById(@CacheKey int id, @CacheValue String newValue) {
        log.info("updateById,id={},newValue={}", id, newValue);
        return newValue;
    }

    @CacheRemove(cacheName = "myCache")
    @Override
    public void deleteById(@CacheKey int id) {
        log.info("deleteById,id={}", id);
    }
}

 

 

参考:https://developer.aliyun.com/article/786959。

标签:JCache,缓存,Cache,介绍,cache,key,import,myCache
From: https://www.cnblogs.com/wuyongyin/p/18019821

相关文章

  • java参数类型详细介绍(简单易懂)
    目录1、参数类型分布图1.1浮点型1.2 字符型char 1.2.1 char大小1.3字符串:(String-不可变字符串)1.3.1Jvm内存图1.3.2开辟空间个数注意1.3.3使用==时注意1.3.4字符串拼接举例 1.3.5String常见的方法1.4字符串:(StringBuffer-可变字符串、StringBuilder-可变......
  • 【MyBatis-Plus】最优化持久层开发 快速入门 核心功能介绍与实战 3.5.3.1
    文章目录一、简介二、快速入门三、MyBatis-Plus核心功能3.1基于Mapper接口CRUD3.1.1Insert方法3.1.2Delete方法3.1.3Update方法3.1.4Select方法3.1.5自定义和多表映射3.2基于Service接口CRUD3.2.1对比Mapper接口CRUD区别:3.2.2使用Iservice接口方式3.2.3CRUD方......
  • 介绍分治算法
    分治算法是一种将问题划分成多个更小的子问题,并且分别解决这些子问题的策略。它通常包含三个步骤:分解(Divide):将原始问题划分成若干个更小的子问题。这个步骤可以使用递归实现,每次递归处理的子问题规模都要比原始问题小。解决(Conquer):递归地解决各个子问题,如果问题规模足够小,......
  • serdes介绍
    高速通信接口:SERDES技术被广泛应用于高速通信接口,如PCIe、USB、SATA、Ethernet等。它能够将大量数据并行化转换为高速串行数据流,以实现高带宽和远距离传输。光纤通信:在光纤通信中,SERDES用于将电信号转换为光信号,并进行光电信号的互转。光纤通信中的SERDES技术可以实......
  • 【Qt】使用Qt实现Web服务器(一):QtWebApp介绍、演示
    1、简介QtWepApp是使用Qt实现的Web服务器库,虽然名字中有“App”但是它的确是一个lib库,编译生产的是libQtWebAppd.so作者开发QtWepApp是从JavaServlet获得的灵感,本人不懂Java,对本人没有帮助。QtWepApp是一个跨平台的项目,适用于:Linux、Windows、MacOS和QtFramework支......
  • kubernetes的kubectl命令介绍
    前言:kubectl是Kubernetes命令行工具,用于与Kubernetes集群进行交互。它允许用户执行各种操作,包括管理容器、部署应用程序、查看集群状态等。kubectl是操作k8s集群的命令行工具,安装在k8s的master节点,kubectl在$HOME/.kube目录中查找一个名为config的文件,你可以通过设置Kube......
  • 【数据库】数据库介绍
    文章目录一、数据库介绍二、SQL分类一、数据库介绍什么是数据库存储数据用文件就可以了,为什么还要弄个数据库?文件保存数据有以下几个缺点:文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便数据库存储介质:磁盘内存为......
  • 【Python使用】python高级进阶知识md总结第4篇:静态Web服务器-命令行启动动态绑定端口
    python高级进阶全知识知识笔记总结完整教程(附代码资料)主要内容讲述:操作系统,虚拟机软件,Ubuntu操作系统,Linux内核及发行版,查看目录命令,切换目录命令,绝对路径和相对路径,创建、删除文件及目录命令,复制、移动文件及目录命令,终端命令格式的组成,查看命令帮助。HTTP请求报文,HTTP响应报文......
  • 眼图的基本介绍
    学习来源:https://www.bilibili.com/video/BV1HA4m137JU/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=432ba293ecfc949a4174ab91ccc526d6 眼图是指为测试传输信号性能,而在示波器上观察到传输信号信息的一种图形,数字信号是以二进制码0101的形式......
  • 主流开发语言和开发环境介绍
    主流开发语言和开发环境介绍随着信息技术的快速发展,软件开发已经成为各行各业的核心需求。在软件开发过程中,选择一种合适的开发语言以及相应的开发环境对于项目的成功实施至关重要。本文将介绍一些主流的开发语言以及常用的开发环境。主流的开发语言有Java,C++,C#,PHP,Python,Jav......