一、Spring从3.1开始支持Cache

Spring 从 3.1 开始就引入了对 Cache 的支持。定义了 org.springframework.cache.Cacheorg.springframework.cache.CacheManager接口来统一不同的缓存技术。并支持使用 JCache(JSR-107)注解简化我们的开发。

其使用方法和原理都类似于 Spring 对事务管理的支持,Spring Cache 是作用在方法上的,其核心思想是,当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存在缓存中。
SpringBoot中提供的缓存注解@Cacheable,@Cacheable会将方法的返回值作为缓存的value,默认将方法的参数值作为缓存的key。@Cacheable可以标记在某个具体的方法上,也可以标记带一个类上,表示该类的所有方法都支持缓存。

每次调用需要缓存功能的方法时,Spring 会检查指定参数的指定目标方法是否已经被调用过,如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户,下次调用直接从缓存中获取。

二、@Cacheable常用属性

  1. @Cacheable添加缓存,相同条件的查询不再查询数据库,而是从缓存中查询;
  2. @CachePut每次都会访问数据库,并更新缓存;
  3. @CacheEvict清除缓存;
    SpringBoot通过@Cacheable注解实现缓存功能-LMLPHP

1、value/cacheNames

如上图所示,这两个属性代表的意义相同,这两个属性都是用来指定缓存组件的名称,即将方法的返回结果放在哪个缓存中,属性定义为数组,可以指定多个缓存;

2、key

可以通过 key 属性来指定缓存数据所使用的的 key,默认使用的是方法调用传过来的参数作为 key。最终缓存中存储的内容格式为:Entry<key,value> 形式。

3、condition

触发条件。这个参数是规定这个缓存触发的条件拼接,例如 condition="#area.id != 1",就是在id不为1的时候触发缓存。

4、unless

排除条件。这个参数是规定这个缓存在何时不触发,例如 unless="#result == null",不对查询结果为NULL的结果进行缓存。

5、keyGenerator

自定义的Key策略,比如缓存的Key值就是方法名。

@Configuration
public class CacheConfig{
	@Bean
	public KeyGenerator myKeyGenerator(){
		return (target,method,params)->method.getName();
	} 
}

KeyGenerator 是Spring提供的一个函数式接口。

package org.springframework.cache.interceptor;

import java.lang.reflect.Method;

/**
 * Cache key generator. Used for creating a key based on the given method
 * (used as context) and its parameters.
 *
 * @author Costin Leau
 * @author Chris Beams
 * @author Phillip Webb
 * @since 3.1
 */
@FunctionalInterface
public interface KeyGenerator {

	/**
	 * Generate a key for the given method and its parameters.
	 * @param target the target instance
	 * @param method the method being called
	 * @param params the method parameters (with any var-args expanded)
	 * @return a generated key
	 */
	Object generate(Object target, Method method, Object... params);

}

通过@Cacheable(keyGenerator=“myKeyGenerator”)指定Key自定义的生成策略。

6、sync

是否使用异步模式,默认是方法执行完,以同步的方式将方法返回的结果存在缓存中。

7、cacheManager

可以用来指定缓存管理器,从哪个缓存管理器里面获取缓存。

三、整合步骤

1、加入pom

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

2、启动类加@EnableCaching注解

3、controller或service加@Cacheable注解即可

四、代码实例

package com.nezha.controller;

import com.nezha.entity.Area;
import com.nezha.service.area.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/area")
public class AreaController {

    @Autowired
    private AreaService areaService;

	// @Cacheable添加缓存,相同条件的查询不再查询数据库,而是从缓存中查询
    @Cacheable(cacheNames="area",key = "#id")
    @GetMapping("getAreaById")
    public Area getAreaById(Integer id) {
        return areaService.getAreaById(id);
    }

	// @CachePut每次都会访问数据库,并更新缓存
    @CachePut(cacheNames="area",key = "#id")
    @PostMapping("updateAreaById")
    public void updateAreaById(Integer id) {
        areaService.updateAreaById(id);
    }

	// @CacheEvict清除缓存
    @CacheEvict(cacheNames="area",key = "#id")
    @PostMapping("deleteAreaById")
    public void deleteAreaById(Integer id) {
        areaService.deleteAreaById(id);
    }
}

通过postman访问127.0.0.1:8080/NettyProject/area/getAreaById?id=1,第一次时控制台输出sql日志,第二次请求时,控制台无日志输出,证明未进行sql查询,查询的是@Cacheable(cacheNames="area",key = "#id")缓存的数据。


🏆本文收录于,Spring Boot 进阶实战

SpringBoot从0到1,递进式学习,精通SpringBoot指日可待

🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师

五、Spring Boot源码解读与原理剖析

本书前身是掘金社区销量TOP的小册——《Spring Boot源码解读与原理剖析》,整个社区中有3600+开发者都不约而同地选择了这本小册,也使它成为掘金社区首屈一指的王牌Spring教程,非常能打!

这本小册让作者跃居2020年度人气榜Top 40,喜提8枚荣誉勋章,站内销量遥遥领先,读者们称其为良心之作,纷纷点赞、打Call。

不过,由于小册的体量和篇幅有限,读者们纷纷表示意犹未尽,干货能够再干、再多一点就好了,希望作者能够讲得更详细、更透彻。

这不,同名书说来就来,比小册内容更丰富、更充实。

如果你想拥有一段相对合理、平滑、系统的学习体验,这本书简直再合适不过了。

SpringBoot通过@Cacheable注解实现缓存功能-LMLPHP

由于本书是基于小册进行的升级,全书内容更加系统化,并且深度结合小册读者反馈给出了针对性优化,讲解更深入与详细。不仅是升级,更是焕新!

不同于小册里的集中式知识讲解,Linked-Bear将内容重新规划拆分成以下四大部分,由浅入深地讲解知识。

第1部分:Spring Boot底层依赖的核心容器

主要介绍的底层基础知识,旨在帮作者打牢基础。先从整体层面回顾Spring Boot知识,让读者快速复习Spring Boot的底层逻辑和核心知识。这些知识是后续编程和应用的基础。

第2部分:Spring Boot的生命周期原理分析

以生命周期各时期发出的Event事件为主线,结合每个生命周期内完成的大事记,让你总览Spring Boot的全貌,更深入地理解Spring Boot。

第3部分:Spring Boot整合常用开发场景

对应前两部分中核心容器讲解模块的配置,演示不同场景下的模块应用。这部分内容十分贴近实战,电商、网关服务、数据库等场景都可以用到这些技术。

第4部分:Spring Boot应用的运行

Spring Boot有多种打包方式,作者选取了两种方式通过分别讲解应用的引导启动流程,并介绍了新版本引入的优雅停机特性。学完这章,你的Spring Boot彻底就能彻底跑通!他专注于分布式系统和机器学习算法的研究,在理论、机器学习、应用和操作系统等多个领域的顶级学术会议上发表过论文。

SpringBoot通过@Cacheable注解实现缓存功能-LMLPHP

08-31 10:12