springboot基础01 – 缓存的使用

前两天解决了一个Spring缓存的问题,因此就想到记录一下spring-boot缓存的使用。

开启缓存

SpringBoot开启缓存也容易,在启动类上添加

@
EnableCaching


注解就可以了,不需要过多的配置。此时开启的缓存是比较简单的缓存,即基于ConcurrentHashMap实现的缓存。虽然简单,但对于负载不高的应用也足够用了。

SpringBoot缓存两个关键类是:

CacheAutoConfiguration




CacheAspectSupport


。这两个类分别位于spring-boot-autoconfigure和spring-context包。也就是说不使用 spring-boot-starter-cache
包也能在spring-boot中使用简单的缓存。



CacheType


类中可以看到SpringBoot支持的缓存类型。懒得一个一个介绍了,直接看下代码好了:

public enum CacheType {
 
	/**
	 * Generic caching using 'Cache' beans from the context.
	 */
	GENERIC,
 
	/**
	 * JCache (JSR-107) backed caching.
	 */
	JCACHE,
 
	/**
	 * EhCache backed caching.
	 */
	EHCACHE,
 
	/**
	 * Hazelcast backed caching.
	 */
	HAZELCAST,
 
	/**
	 * Infinispan backed caching.
	 */
	INFINISPAN,
 
	/**
	 * Couchbase backed caching.
	 */
	COUCHBASE,
 
	/**
	 * Redis backed caching.
	 */
	REDIS,
 
	/**
	 * Caffeine backed caching.
	 */
	CAFFEINE,
 
	/**
	 * Simple in-memory caching.
	 */
	SIMPLE,
 
	/**
	 * No caching.
	 */
	NONE
 
}

可以看到,支持了差不多所有的主流缓存。

缓存注解

spring boot的缓存主要是由注解支持实现的。下面是几个常见的注解:



  • @
    Cacheable


    :针对方法进行配置,根据方法的请求参数缓存返回值,如无缓存值则执行方法;


  • @
    CacheEvict


    :用于移除缓存记录,调用方法时会执行移除操作;


  • @
    CachePut


    :用于更新缓存记录;保证方法一定会被调用,同时缓存方法返回值;与@Cacheable的区别在于是否每次都调用方法;


  • @
    CacheConfig


    :统一配置管理类内部所有缓存注解的属性。




@
Cacheable




@
CachePut


注解属性说明

  • keyGenerator:缓存数据key生成策略;
  • CacheManager:缓存管理器,管理缓存组件;
  • CacheResolver:缓存解析器,根据实际情况动态解析决定使用哪个缓存实例
  • value:缓存实例(一个缓存实例可以存储多个缓存KV对)的名称,至少需要设置一个;
  • key:缓存的 key,如果不为空需要要按照 SpEL 表达式编写;如果不为空则缺省按照方法的所有参数进行组合;
  • condition:缓存条件,使用 SpEL 编写;若不为空,只在条件结果为 true 时才进行缓存;
  • unless:缓存排除条件,当条件结果为TRUE时不会缓存;
  • sync:是否同步操作,如为true,那么多个线程访问同一条记录时,会同步执行调用的方法。




@
CacheEvict


注解属性说明



@
CacheEvict


注解的属性大致同

@
Cacheable


一致,不过

@
CacheEvict


还有两个独有的属性:

  • allEntries:是否清空所有缓存内容,缺省为 false;如果指定为 true,则方法调用后将立即清空所有缓存;
  • beforeInvocation:是否在方法执行前就清空,缺省为 false;如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存。




@
CacheConfig


注解属性说明



@
CacheConfig


注解的属性

@
Cacheable


都有。因为

@
CacheConfig


注解的作用本来就是统一管理相同类下所有方法的缓存配置。

需要提一下的就是在spring4.1之前是没有

@
CacheConfig


注解的,那时候需要在每个方法的

@
Cacheable


注解中设置 cacheNames
属性。

SpEL表达式

下面简单介绍下SpEL表达式的语法——看下表的,摘自Spring官方文档:

名称 位置 描述 示例
methodName root对象 当前被调用的方法名 #root.methodname
method root对象 当前被调用的方法 # root.method.name
target root对象 当前被调用的目标对象实例 #root.target
targetClass root对象 当前被调用的目标对象的类 #root.targetClass
args root对象 当前被调用的方法的参数列表 #root.args[0]
caches root对象 当前方法调用使用的缓存列表 #root.caches[0].name
Argument Name 执行上下文 当前被调用的方法的参数,如findArtisan(Artisan artisan),可以通过#artsian.id获得参数 # artsian.id
result 执行上下文 方法执行后的返回值(仅当方法执行后的判断有效,如 unless cacheEvict的beforeInvocation=false) #result

注意事项:

  1. 当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性, 如

    @
    Cacheable
    (
    key
    =
    "targetClass + methodName +#p0"
    )


    ;
  2. 使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”,如:

    @
    Cacheable
    (
    value
    =
    "users"
    ,
    key
    =
    "#id"
    )




    @
    Cacheable
    (
    value
    =
    "users"
    ,
    key
    =
    "#p0"
    )


类型 运算符
关系 <,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne
算术 +,- ,* ,/,%,^
逻辑 &&,||,!,and,or,not,between,instanceof
条件 ?: (ternary),?: (elvis)
正则表达式 matches
其他类型 ?.,?[…],![…],^[…],$[…]

使用Caffeine缓存

前面的配置,即只在在启动类上添加

@
EnableCaching


注解的情形下,我们只能使用最基础的

SIMPLE


缓存。现在我们需要尝试使用Caffeine缓存,就需要再多做些配置了。

在做这个配置的时候遇到了些问题,所以在这里也简单记录下解决问题的过程。

首先,需要在配置文件中指明使用Caffine缓存并添加Caffeine缓存的配置:

spring:
  cache:
    type: CAFFEINE
    caffeine:
      spec: initialCapacity=1048576,maximumSize=1073741824,expireAfterAccess=10m

然后加入Caffeine缓存依赖:

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

然而此时调用方法会发现启动失败,报错如下:

Caused by: java.lang.IllegalArgumentException: No cache manager could be auto-configured, check your configuration (caching type is 'CAFFEINE')
	at org.springframework.util.Assert.notNull(Assert.java:215)
	at org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration$CacheManagerValidator.afterPropertiesSet(CacheAutoConfiguration.java:107)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
	... 42 common frames omitted

提示缺少CacheManager,说实话一开始看到这个错误提示我是不知咋回事儿的。

将spring-boot的debug配置设置为true,再重新执行,会有如下提示:

   CaffeineCacheConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'com.github.benmanes.caffeine.cache.Caffeine', 'org.springframework.cache.caffeine.CaffeineCacheManager' (OnClassCondition)

提示Caffeine缓存的自动配置需要两个类

com
.
github
.
benmanes
.
caffeine
.
cache
.
Caffeine




org
.
springframework
.
cache
.
caffeine
.
CaffeineCacheManager


。前者在引入caffeine的jar以后已经不是问题,后者则需要引入新的依赖。



CaffeineCacheManager


这个类位于spring-context-support中,我们可以直接引入这个依赖,不过更推荐通过spring-boot-starter-cache来间接引入,这样指向性会更明确一些。

spring-boot-starter-cache依赖如下:

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

添加spring-boot-starter-cache依赖后再次测试,应用启动正常,缓存正常。

如需引入其他类型的缓存,也可以按类似的步骤来进行配置。

就这样。写了个示例应用,放在github了,有需要可以看一下: spring-boot-cache

噢,对了,Caffeine缓存在spring-boot下有个坑,以前踩到过,记录在这里了: 《spring caffeine缓存慎用weakKeys》

原文 

https://www.zhyea.com/2019/08/25/springboot-base-using-cache.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » springboot基础01 – 缓存的使用

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址