当前位置: 首页 > article >正文

SpringCache之本地缓存

针对不同的缓存技术,需要实现不同的cacheManager,Spring定义了如下的cacheManger实现。

CacheManger

描述

SimpleCacheManager

使用简单的Collection来存储缓存,主要用于测试

ConcurrentMapCacheManager

使用ConcurrentMap作为缓存技术(默认),需要显式的删除缓存,无过期机制

NoOpCacheManager

仅测试用途,不会实际存储缓存

EhCacheCacheManager

使用EhCache作为缓存技术,以前在hibernate的时候经常用

GuavaCacheManager

使用google guava的GuavaCache作为缓存技术(1.5版本已不建议使用)

CaffeineCacheManager

是使用Java8对Guava缓存的重写,spring5(springboot2)开始用Caffeine取代guava

HazelcastCacheManager

使用Hazelcast作为缓存技术

JCacheCacheManager

使用JCache标准的实现作为缓存技术,如Apache Commons JCS

RedisCacheManager

使用Redis作为缓存技术

常规的SpringBoot已经为我们自动配置了EhCache、Collection、Guava、ConcurrentMap等缓存,默认使用ConcurrentMapCacheManager。SpringBoot的application.properties配置文件,使用spring.cache前缀的属性进行配置。

使用

1.添加依赖

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

2.添加配置类

2.1 ConcurrentMapCacheManager,

spring默认就是ConcurrentMapCache,如果不指定缓存名称,可以不加配置类,直接@EnableCaching写道启动类上

@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {

    @Bean("ConcurrentMapCacheManager")
    @Primary
    public CacheManager caffeineCacheManager() {
        ConcurrentMapCacheManager concurrentMapCacheManager = new ConcurrentMapCacheManager();
        //可以事先指定chcheName
        //Collection<String> cacheNames = concurrentMapCacheManager.getCacheNames();
        //if (CollectionUtils.isEmpty(cacheNames)){
        //    集合
        //    concurrentMapCacheManager.setCacheNames();
        //}
        return concurrentMapCacheManager;
    }

}

2.2 caffeine

同理,如果不需要特殊参数,加入依赖后也可不写配置类

<!-- 使用  caffeine https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine -->
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
            <version>2.6.0</version>
        </dependency>
@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {

    @Bean("caffeineCacheManager")
    @Primary
    public CacheManager caffeineCacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        // 方案一(常用):定制化缓存Cache
        cacheManager.setCaffeine(Caffeine.newBuilder()
                // 缓存项在写入后的过期时间为 5 分钟。
                .expireAfterWrite(5, TimeUnit.MINUTES)
                //设置缓存的初始容量为 100 个缓存项。
                .initialCapacity(100)
                //设置缓存的最大容量为 200 个缓存项。
                .maximumSize(200));
        return cacheManager;
    }
}

3.使用

主要基于Spring缓存注解@Cacheable、@CacheEvict、@CachePut的方式使用

  1. @Cacheable :改注解修饰的方法,若不存在缓存,则执行方法并将结果写入缓存;若存在缓存,则不执行方法,直接返回缓存结果。
  2. @CachePut :执行方法,更新缓存;该注解下的方法始终会被执行。
  3. @CacheEvict :删除缓存

3.1cacheable

调用这个方法的时候,会从缓存中查询,如果没有,查询数据库并将执行的结果存入缓存中,否则返回缓存中的对象。

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个,就是缓存的首个前缀

例如:
@Cacheable(value=”room”)
@Cacheable(value={”room1”,”room2”}

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@Cacheable(value=”room”,key=”#userId”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@Cacheable(value=room”,condition=”#userId > 2”)

@Component
public class UserCache {
    @Cacheable(cacheNames = "room", key = "#userId")
    public User getUserId(Interger userId){
        return queryuser();
    }
}

3.2 CachePut

主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个

@CachePut(value=room”)

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合,也可以使用返回值结果字段result

@CachePut(value=”room”,key=”#userId”)

@CachePut(value=”room”,key=”#result.userId”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@CachePut(value=”room”,condition=”#userId>2”)

@Component
public class UserCache {
    @CachePut(cacheNames = "room", key = "#result.deptId+':'+#userId")
    public User getUserId(String userId){
       return queryuser();
    }

}

3.3@CachEvict

主要针对方法配置,能够根据一定的条件对缓存进行清空

参数

解释

example

value

缓存的名称,在 spring 配置文件中定义,必须指定至少一个

@CacheEvict(value=”my cache”)

key

缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@CacheEvict(value=”testcache”,key=”#userName”)

condition

缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@CacheEvict(value=”testcache”,condition=”#userName.length()>2”)

allEntries

是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存

@CachEvict(value=”testcache”,allEntries=true)

beforeInvocation

是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存

@CachEvict(value=”testcache”,beforeInvocation=true)

@Component
public class UserCache {

    @CacheEvict(cacheNames = "room")
    public User getUserId(String userId){
        return null;
    }

}

3.4 cacheManager的简单使用

//获取缓存
Cache user = cacheManager.getCache("room");
//获取所有缓存数据
User nativeCache = (User)user.getNativeCache();
//获取某个key的数据
Object o1 = user.get("1").get();
//存入数据
 user.putIfAbsent(Object var1, @Nullable Object var2);
 user.put(Object var1, @Nullable Object var2);
//清空数据
user.evictIfPresent("room");

spring cache源码

public interface Cache {
    String getName();

    Object getNativeCache();

    @Nullable
    ValueWrapper get(Object var1);

    @Nullable
    <T> T get(Object var1, @Nullable Class<T> var2);

    @Nullable
    <T> T get(Object var1, Callable<T> var2);

    void put(Object var1, @Nullable Object var2);

    @Nullable
    default ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
        ValueWrapper existingValue = this.get(key);
        if (existingValue == null) {
            this.put(key, value);
        }

        return existingValue;
    }

    void evict(Object var1);

    default boolean evictIfPresent(Object key) {
        this.evict(key);
        return false;
    }

    void clear();

    default boolean invalidate() {
        this.clear();
        return false;
    }

    public static class ValueRetrievalException extends RuntimeException {
        @Nullable
        private final Object key;

        public ValueRetrievalException(@Nullable Object key, Callable<?> loader, Throwable ex) {
            super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);
            this.key = key;
        }

        @Nullable
        public Object getKey() {
            return this.key;
        }
    }

    @FunctionalInterface
    public interface ValueWrapper {
        @Nullable
        Object get();
    }
}

caffeine扩展的loadingCache

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.github.benmanes.caffeine.cache;

import java.util.Map;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

public interface LoadingCache<K, V> extends Cache<K, V> {
    @Nullable V get(@NonNull K var1);

    @NonNull Map<@NonNull K, @NonNull V> getAll(@NonNull Iterable<? extends @NonNull K> var1);

    void refresh(@NonNull K var1);
}

http://www.kler.cn/a/299941.html

相关文章:

  • 豆瓣Top250电影的数据采集与可视化分析(scrapy+mysql+matplotlib)
  • C语言文件操作
  • js学习笔记(2)
  • C语言数组详解:从基础到进阶的全面解析
  • linux+docker+nacos+mysql部署
  • 【2024年华为OD机试】 (C卷,200分)- 字符串拼接(JavaScriptJava PythonC/C++)
  • 自动化抢票 12306
  • 苹果iOS/ iPadOS18 RC 版、17.7 RC版更新发布
  • Mybatis-Plus笔记
  • Mac OS14外接显示器字体过小和放大字体模糊问题的简单解决
  • FIFO求和实验
  • 电脑点击关机之后,又自动重启开机了。根本就关不了?
  • 关于Python爬虫的基础知识
  • 云计算实训48——k8s环境搭建(详细版)
  • 数据结构——堆排序
  • OGRE 3D----创建第一个OGRE 3D示例
  • YashanDB产品调优实战:分享日常调优技巧及提升系统性能的实战经验
  • 【Hot100算法刷题集】双指针-01-移动零(含置零思路、移动思路、偏移量思路、冒泡法)
  • 支付环节攻击方式与漏洞类型
  • OPENAIGC开发者大赛企业组钻石奖 | AI For 3D Generation
  • RQ-RAG:提升检索增强生成模型的查询精炼能力
  • 中间件漏洞
  • 【稀疏矩阵】使用torch.sparse模块
  • (k8s)kubernetes 挂载 minio csi 的方式
  • 2024年消防设施操作员考试题库及答案
  • 52. 两个链表的第一个公共节点