Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中将取代Guava。如果出现Caffeine,CaffeineCacheManager将会自动配置。使用spring.cache.cache-names属性可以在启动时创建缓存,并可以通过以下配置进行自定义(按顺序):

  • spring.cache.caffeine.spec: 定义的特殊缓存
  • com.github.benmanes.caffeine.cache.CaffeineSpec: bean定义
  • com.github.benmanes.caffeine.cache.Caffeine: bean定义

例如,以下配置创建一个foo和bar缓存,最大数量为500,存活时间为10分钟:

spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

除此之外,如果定义了com.github.benmanes.caffeine.cache.CacheLoader,它会自动关联到CaffeineCacheManager。由于该CacheLoader将关联被该缓存管理器管理的所有缓存,所以它必须定义为CacheLoader<Object, Object>,自动配置将忽略所有泛型类型。

1.引入依赖

  <properties>
<caffeine.cache.version>2.7.0</caffeine.cache.version>
</properties> <dependencies>
<!-- Spring boot Cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--for caffeine cache-->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.cache.version}</version>
</dependency>
</dependencies>

2.configuration

 @EnableCaching
@Configuration
public class CaffeineCacheConfig {
public static final Integer CAFFEINE_MAXSIZE = PropertyUtil.getInt("caffeine.maxsize", "10000");
public static final Integer CAFFEINE_EXPIRE_TIME = PropertyUtil.getInt("caffeine.expire.time", "3"); /**
* 创建基于Caffeine的Cache Manager
* @return
*/
@Bean("caffeineCacheManager")
public CacheManager CaffeineCacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder().recordStats()
.expireAfterWrite(CAFFEINE_EXPIRE_TIME, TimeUnit.SECONDS)
.maximumSize(CAFFEINE_MAXSIZE)); return cacheManager;
} }

使用@EnableCaching注解让Spring Boot开启对缓存的支持

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不可以同时使用

3.service

 @Service("caffeineCacheService")
public class CaffeineCacheServiceImpl {
@Autowired
CacheManager caffeineCacheManager; private final static String DEFAULT_CACHE = "default"; public <T> T getValue(Object key) {
if(key == null) return null; Cache cache = caffeineCacheManager.getCache(DEFAULT_CACHE);
if(cache != null) {
Cache.ValueWrapper wrapper = cache.get(key);
if (wrapper != null)
return (T) wrapper.get();
} return null;
} public <T> T getValue(String cacheName, Object key) {
if(cacheName == null || key == null) return null; Cache cache = caffeineCacheManager.getCache(cacheName);
if(cache != null) {
Cache.ValueWrapper wrapper = cache.get(key);
if (wrapper != null)
return (T) wrapper.get();
} return null;
} public void putValue(Object key, Object value) {
if(key == null || value == null) return; Cache cache = caffeineCacheManager.getCache(DEFAULT_CACHE);
if(cache != null) {
cache.put(key, value);
}
} public void putValue(String cacheName, Object key, Object value) {
if(cacheName == null || key == null || value == null) return; Cache cache = caffeineCacheManager.getCache(cacheName);
if(cache != null) {
cache.put(key, value);
}
}
}

其中get(key)只是返回了ValueWrapper,具体value需要get方法。我看了caffeineCacheManager.getCache方法,按理说在cachemap中找不到cache的时候会新建一个cache并放入map中再返回,但是看了源码方法上标注了@Nullable,为了代码严谨,选择了判断null。

4.实例

     private static Integer uuid = 0;
@Cacheable(value = DEFAULT_CACHE, key = "#pin")
public Integer getUUid(String pin) {
/*
if(getValue(pin) != null) {
return getValue(pin);
}*/ return uuid++;
}

附:spring cache相关注解介绍 @Cacheable、@CachePut、@CacheEvict

@Cacheable
@Cacheable是用来声明方法是可缓存的。将结果存储到缓存中以便后续使用相同参数调用时不需执行实际的方法。直接从缓存中取值。最简单的格式需要制定缓存名称。
例如:

 @Cacheable("books")
public Book findBook(ISBN isbn) {...}

在上面的代码片段中,findBook方法与名为books的缓存想关联。每次调用该方法时,将在缓存中检查该请求是否已执行,以免重复执行。虽然在大多数情况下,只有一个缓存被声明,注释允许指定多个名称,以便使用多个缓存。这种情况下,在执行方法之前,每个缓存都会检查之前执行的方法,只要有一个缓存命中,即直接从缓存中返回相关的值。
即使没有实际执行缓存方法,所有其他不包含该值的缓存也将被更新。
例如:

 @Cacheable({"books", "isbns"})
public Book findBook(ISBN isbn) {...}

默认key生成:
默认key的生成按照以下规则:
- 如果没有参数,则使用0作为key
- 如果只有一个参数,使用该参数作为key
- 如果又多个参数,使用包含所有参数的hashCode作为key

自定义key的生成:
当目标方法参数有多个时,有些参数并不适合缓存逻辑
比如:

 @Cacheable("books")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

其中checkWarehouse,includeUsed并不适合当做缓存的key.针对这种情况,Cacheable 允许指定生成key的关键属性,并且支持支持SpringEL表达式。(推荐方法)
再看一些例子:

 @Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) @Cacheable(cacheNames="books", key="#map['bookid'].toString()")
public Book findBook(Map<String, Object> map)

缓存的同步 sync:
在多线程环境下,某些操作可能使用相同参数同步调用。默认情况下,缓存不锁定任何资源,可能导致多次计算,而违反了缓存的目的。对于这些特定的情况,属性 sync 可以指示底层将缓存锁住,使只有一个线程可以进入计算,而其他线程堵塞,直到返回结果更新到缓存中。
例:

 @Cacheable(cacheNames="foos", sync="true")
public Foo executeExpensiveOperation(String id) {...}

属性condition:
有时候,一个方法可能不适合一直缓存(例如:可能依赖于给定的参数)。属性condition支持这种功能,通过SpEL 表达式来指定可求值的boolean值,为true才会缓存(在方法执行之前进行评估)。
例:

 @Cacheable(cacheNames="book", condition="#name.length < 32")
public Book findBook(String name)

此外,还有一个unless 属性可以用来是决定是否添加到缓存。与condition不同的是,unless表达式是在方法调用之后进行评估的。如果返回false,才放入缓存(与condition相反)。 #result指返回值 例:

 @Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.name.length > 5"")
public Book findBook(String name)

@CachePut
如果缓存需要更新,且不干扰方法的执行,可以使用注解@CachePut。@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

 @CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)

注意:应该避免@CachePut 和 @Cacheable同时使用的情况。

@CacheEvict
spring cache不仅支持将数据缓存,还支持将缓存数据删除。此过程经常用于从缓存中清除过期或未使用的数据。
@CacheEvict要求指定一个或多个缓存,使之都受影响。此外,还提供了一个额外的参数allEntries 。表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素。

 @CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch)

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

 @CacheEvict(cacheNames="books", beforeInvocation=true)
public void loadBooks(InputStream batch)

@CacheConfig
有时候一个类中可能会有多个缓存操作,而这些缓存操作可能是重复的。这个时候可以使用@CacheConfig

 @CacheConfig("books")
public class BookRepositoryImpl implements BookRepository { @Cacheable
public Book findBook(ISBN isbn) {...}
}

@CacheConfig是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。
该操作会被覆盖。

开启缓存注解
java类配置:

 @Configuration
@EnableCaching
public class AppConfig {
}

XML 配置:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <cache:annotation-driven /> </beans>

Caffeine用法的更多相关文章

  1. 一个缓存使用案例:Spring Cache VS Caffeine 原生 API

    最近在学习本地缓存发现,在 Spring 技术栈的开发中,既可以使用 Spring Cache 的注解形式操作缓存,也可用各种缓存方案的原生 API.那么是否 Spring 官方提供的就是最合适的方案 ...

  2. pandas用法小结

    前言 个人感觉网上对pandas的总结感觉不够详尽细致,在这里我对pandas做个相对细致的小结吧,在数据分析与人工智能方面会有所涉及到的东西在这里都说说吧,也是对自己学习的一种小结! pandas用 ...

  3. Caffeine缓存

    在本文中,我们来看看 Caffeine — 一个高性能的 Java 缓存库. 缓存和 Map 之间的一个根本区别在于缓存可以回收存储的 item. 回收策略为在指定时间删除哪些对象.此策略直接影响缓存 ...

  4. Caffeine Cache-高性能Java本地缓存组件

    前面刚说到Guava Cache,他的优点是封装了get,put操作:提供线程安全的缓存操作:提供过期策略:提供回收策略:缓存监控.当缓存的数据超过最大值时,使用LRU算法替换.这一篇我们将要谈到一个 ...

  5. springboot中使用Caffeine本地缓存

    Caffeine是使用Java8对Guava缓存的重写版本性能有很大提升 一 依赖 <dependency> <groupId>org.springframework.boot ...

  6. 一文深入了解史上最强的Java堆内缓存框架Caffeine

    它提供了一个近乎最佳的命中率.从性能上秒杀其他一堆进程内缓存框架,Spring5更是为了它放弃了使用多年的GuavaCache 缓存,在我们的日常开发中用的非常多,是我们应对各种性能问题支持高并发的一 ...

  7. [译]高性能缓存库Caffeine介绍及实践

    概览 本文我们将介绍Caffeine-一个Java高性能缓存库.缓存和Map之间的一个根本区别是缓存会将储存的元素逐出.逐出策略决定了在什么时间应该删除哪些对象,逐出策略直接影响缓存的命中率,这是缓存 ...

  8. Caffeine缓存详解

    概要 Caffeine是一个高性能,高命中率,低内存占用,near optimal 的本地缓存,简单来说它是 Guava Cache 的优化加强版,有些文章把 Caffeine 称为"新一代 ...

  9. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

随机推荐

  1. [转]JS如何判断一个对象是否为空、是否有某个属性

    原文地址:https://www.cnblogs.com/crackedlove/p/10039105.html 一.js判断一个对象是否为空 方法一: let obj1 = {} let obj2 ...

  2. wordpress 访问其他数据库

    有时候我们需要在 Worpdress 中访问其他服务器上的数据库时,可以使用以下方式,在 functions.php 中添加如下代码: // 输入数据库配置参数$mydb = new wpdb('us ...

  3. avformat_open_input阻塞操作中断的支持

    avformat_open_input默认是阻塞操作,如果不加控制,等待时间可能会达到30s以上,对于有些情况,等待30s的体验是无法接受的. ffmpeg支持interrupt_callback机制 ...

  4. VUE-013-为elementUI 设置 tootip 宽度

    在表格显示列表中,通常添加 :show-overflow-tooltip="true" 以显示不能完全展示的单元格文案提示.单通常显示为全屏宽度,不易查看,可通过设置全局的样式,进 ...

  5. 【转】WPF DataGridComboBoxColumn使用

    若要填充下拉列表,请首先使用下列选项之一设置 ComboBox 的 ItemsSource 属性.静态资源. x:Static 代码实体.ComboBoxItem 类型的内联集合.实现效果如下: 如需 ...

  6. 如何分析redis中的慢查询

    慢查询的两个参数配置 慢查询只记录命令执行时间,并不包括命令排队和网络传输时间.因此客户端执行命令的时间会大于命令实际执行时间.因为命令执行排队机制,慢查询会导致其他命令级联阻塞,因此当客户端出现请求 ...

  7. TCP/IP和OSI4层、7层协议介绍

    1.TCP/IP全称:Transmission Control Protocol / Internet Protocol 中文翻译:传输控制协议 / 互联网协议 2.OSI4层.7层模型:

  8. Mysql日期函数说明

    1.获取当天日期 current_date  ->   2019-07-17 00:00:00 2.获取昨天日期函数 date_sub(current_date,INTERVAL 1 day)  ...

  9. 【NPDP笔记】第五章 工具与度量

      5.1 创意工具 Ideation 创意开发 创意工具 Scamper Substitute Combine Adapter Modify Put to another use Eliminate ...

  10. (记录问题)1.Canvas.drawArc()方法的问题

    先看看异常: 一眼看去就知道说的是方法找不到错误 后面发现是系统版本过低,4.0的系统找不到5.0后添加的方法报的错. 修改后完美解决