首页 > 其他分享 >Spring Boot缓存注解使用案例

Spring Boot缓存注解使用案例

时间:2023-05-31 23:02:38浏览次数:41  
标签:Cacheable Spring Boot 缓存 key 注解 方法 id

一、spring-boot-cache缓存

1、pom

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

2、main启动类加入@EnableCaching

import org.springframework.cache.annotation.EnableCaching;

@EnableCaching

3、自定义缓存key的命名规则

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Method;

// 自定义缓存的 key生成
@Component
public class MyKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object o, Method method, Object... objects) {
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(o.getClass().getSimpleName())
                .append("_")
                .append(method.getName())
                .append("_")
                .append(StringUtils.arrayToDelimitedString(objects, "_"));
        return stringBuffer.toString();
    }
}

4、在类上使用,访问类所有的方法都缓存

import com.pingan.domain.Student;
import com.pingan.mapper.StudentMapper;
import com.pingan.service.StudentService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

// 在类上加 @Cacheable 代表类下面所有的方法都缓存,cacheNames随便起,keyGenerator为自定义缓存key的bean
@Service("studentService")
@Cacheable(cacheNames = "StudentServiceCache",keyGenerator = "myKeyGenerator")
public class StudentServiceImpl implements StudentService {
    @Resource
    private StudentMapper studentMapper;

    @Override
    public Student queryById(Integer id) {
        return this.studentMapper.queryById(id);
    }
}

 在方法上使用,访问此方法才会缓存

@Cacheable(cacheNames = "StudentServiceCache",keyGenerator = "myKeyGenerator")
public Student queryById(Integer id) {
    return this.studentMapper.queryById(id);
}

5、在更新和插入的方法上加上  @CacheEvict 清空缓存

@CacheEvict(cacheNames = "StudentServiceCache",allEntries = true)
public Student insert(Student student) {
    this.studentMapper.insert(student);
    return student;
}

6、定时任务清缓存

通过定时任务去清缓存

@Autowired
private Demo01Controller demo01Controller;

@Scheduled(cron = "0/4 * * * * *")
public void test03() {
    demo01Controller.test02();    // test02方法上有注解 @CacheEvict
}

 

 



二、spring-boot的文字说明

下SpringBoot的缓存方案,有自带的ConcurrentLinkedHashMap,还有主流的Guava、Caffeine、Ehcache作为入门,先拿自身的来玩玩,也就是ConcurrentLinkedHashMap

一、ConcurrentLinkedHashMap的使用
先简单说一下,此缓存保存在内存中,如果关闭或重启服务,缓存将被清除。如果要长久保存,可以结合Redis使用方式,很简单,抓住这几个注解关键词:@EnableCaching、@Cacheable、@CachePut、@CacheEvict



1.1 @EnableCaching

一般在启动基类上加上此注解,表示打开缓存功能

@SpringBootApplication
@EnableCaching // 打开缓存功能
public class DemoApplication {
}



1.2 @Cacheable

用在获取并缓存数据的方法上,表示此方法有缓存功能。当调用此方法时,会先从缓存中查找

  • 如果缓存里有,就直接返回,不会运行方法内部语句;
  • 如果没有,则执行方法内部语句,然后把返回值缓存起来
/** 临时用HashMap当作数据库 */
private HashMap<Integer, UserBean> users = new HashMap<>();

@Cacheable(cacheNames = "cacheModel", key = "#id", unless = "#result == null")
public UserBean getById(int id) {
    System.out.println("CacheModel.getById:id=" + id);
    UserBean user = new UserBean(id, "name_" + new Random().nextInt(100));
    users.put(id, user);
    return user;
}



1.3 @CachePut

用在更新缓存的方法上,表示更新缓存中的数据。

@CachePut(cacheNames = "cacheModel", key = "#user.id", unless = "#user == null")
public UserBean updateUser(UserBean user){
    System.out.println("CacheModel.updateUser: user=" + user);
    return users.put(user.getId(), user);
}



1.4 @CacheEvict

用在删除缓存的方法上,表示根据条件删除对应的缓存

@CacheEvict(cacheNames = "cacheModel", key = "#id")
public UserBean removeUser(int id) {
    System.out.println("CacheModel.removeUser: id=" + id);
    return users.remove(id);
}

如果要清除cacheNames指定名称的所有缓存,增加参数:allEntries = true

@CacheEvict(cacheNames = "cacheModel", allEntries = true)
public void clear() {
    System.out.println("CacheModel.clear all");
}

 



@Caching这个注解

使用该注解,可以在一个方法或者类上同时指定多个Spring Cache相关的注解

可以指定cacheable、put和evict三个属性,分别对应相应的注解,如@Caching(cacheable = @Cacheable(“users”), evict = { @CacheEvict(“cache2”),@CacheEvict(value = “cache3”, allEntries = true) })

 



@CacheConfig这个注解

抽取类中的所有@CachePut@Cacheable@CacheEvict的公共配置

 

 



@Caching & @CacheConfig

@Caching设置方法的复杂缓存规则

@CacheConfig:抽取类中的所有@CachePut@Cacheable@CacheEvict的公共配置

 

Spring Boot缓存注解使用案例_缓存

 



一、简介

1、缓存介绍

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

其使用方法和原理都类似于 Spring 对事务管理的支持。Spring Cache 是作用在方法上的,其核心思想是,当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存在缓存中。

2、Cache 和 CacheManager 接口说明

  • Cache 接口包含缓存的各种操作集合,你操作缓存就是通过这个接口来操作的。
  • Cache 接口下 Spring 提供了各种 xxxCache 的实现,比如:RedisCache、EhCache、ConcurrentMapCache
  • CacheManager 定义了创建、配置、获取、管理和控制多个唯一命名的 Cache。这些 Cache 存在于 CacheManager 的上下文中。

小结:

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



二、@Cacheable 注解使用详细介绍

1、缓存使用步骤

@Cacheable 这个注解,用它就是为了使用缓存的。所以我们可以先说一下缓存的使用步骤:

1、开启基于注解的缓存,使用 @EnableCaching 标识在 SpringBoot 的主启动类上。

2、标注缓存注解即可

① 第一步:开启基于注解的缓存,使用 @EnableCaching 标注在 springboot 主启动类上

Spring Boot缓存注解使用案例_ehcache_02

② 第二步:标注缓存注解

Spring Boot缓存注解使用案例_ehcache_03

注:这里使用 @Cacheable 注解就可以将运行结果缓存,以后查询相同的数据,直接从缓存中取,不需要调用方法。

2、常用属性说明

下面介绍一下 @Cacheable 这个注解常用的几个属性:

cacheNames/value :用来指定缓存组件的名字

key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)

keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用

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

condition :可以用来指定符合条件的情况下才缓存

unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)

sync :是否使用异步模式。

① cacheNames

用来指定缓存组件的名字,将方法的返回结果放在哪个缓存中,可以是数组的方式,支持指定多个缓存。

Spring Boot缓存注解使用案例_缓存_04

② key

缓存数据时使用的 key。默认使用的是方法参数的值。可以使用 spEL 表达式去编写。

Spring Boot缓存注解使用案例_缓存_05

③ keyGenerator

key 的生成器,可以自己指定 key 的生成器,通过这个生成器来生成 key。

Spring Boot缓存注解使用案例_spring_06

Spring Boot缓存注解使用案例_缓存_07

 

这样放入缓存中的 key 的生成规则就按照你自定义的 keyGenerator 来生成。不过需要注意的是:

@Cacheable 的属性,key 和 keyGenerator 使用的时候,一般二选一。

④ condition

符合条件的情况下才缓存。方法返回的数据要不要缓存,可以做一个动态判断。

Spring Boot缓存注解使用案例_ehcache_08

⑤ unless

否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。

Spring Boot缓存注解使用案例_spring_09

⑥ sync

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

3、spEL 编写 key

前面说过,缓存的 key 支持使用 spEL 表达式去编写,下面总结一下使用 spEL 去编写 key 可以用的一些元数据:

Spring Boot缓存注解使用案例_spring boot_10

 

 

标签:Cacheable,Spring,Boot,缓存,key,注解,方法,id
From: https://blog.51cto.com/lenglingx/6390816

相关文章

  • SpringBoot集成Redis
    依赖包:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><grou......
  • 146. LRU 缓存
    主要是利用LinkedHashMap的功能LinkedHashMap继承了HashMap学到了LinkedHashMap维护双向链表的方法LinkedHashMap的Entry加入了一个before和after,用于维护Entry的加入顺序。next维护各个桶的顺序。回忆LinkedHashMap源码记得看:https://blog.csdn.net/weixin......
  • 《面试1v1》Spring基础
    我是javapub,一名Markdown程序员从......
  • Spring加载Bean有哪些方式
    转载:https://www.bilibili.com/video/BV1AL411B7Zp/?vd_source=46d50b5d646b50dcb2a208d3946b1598......
  • spring cloud 之 openfeign 记录(通过feign上传)
    今日搭建好nacos nacos踩坑记录迫不及待的进入了下一步,服务间的远程调用,就踩了一个小小的坑 我做的是一个阿里oss上传的服务!阿里oss服务个人可以有三个月试用,对新手非常的友好首先是一个openfeign编写上的问题@RequestMapping(value="/common/oss/download",meth......
  • Spring MVC官方文档学习笔记(二)之DispatcherServlet
    1.DispatcherServlet入门(1)SpringMVC是以前端控制器模式(即围绕着一个中央的Servelt,DispatcherServlet)进行设计的,这个DispatcherServlet为请求的处理提供了一个共用的算法,即它都会将实际的处理工作委托给那些可配置的组件进行执行,说白了,DispatcherServlet的作用就是统......
  • springboot整合log4j解决依赖冲突
    首先将web模块的日志排除<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion>......
  • SpringBoot的基础
    1、获取配置文件的值:@Value的方式yml配置文件redis:host:199.22.22.341.1、用法1:普通用法@Value("${redis.host}")privateStringparamName;结果1.2、用法2:冒号(:)的作用冒号(:)的作用:当获取的值没有值时,返回冒号后的预设值默认值@Value("${redis......
  • Java实战-基于JDK的LRU算法实现、优雅的实现代码耗时统计(Spring AOP、AutoCloseable
    场景Java中基于JDK的LRU算法实现LRU算法-缓存淘汰算法-Leastrecentlyused,最近最少使用算法根据数据的历史访问记录来进行淘汰数据,其核心思想是:如果有数据最近被访问过,那么将来被访问的几率也更高在Java中可以利用LinkedHashMap容器简单实现LRU算法LinkedHashMap底层就是用......
  • Spring boot actuator端点启用和暴露
    SpringBoot1.x版本#关闭所有端点endpoints.enabled=false#开启/health端点endpoints.health.enabled=trueSpringBoot2.x版本#关闭所有端点management.endpoints.enabled-by-default=false#开启/health端点management.endpoint.health.enabled=true......