赞
踩
Spring Cache 是 Spring 框架提供的一个抽象层,通过 Spring Cache,你可以将缓存逻辑与业务代码分离,减少对底层缓存实现的依赖。Spring Cache 支持多种缓存提供者,如 EhCache、Redis、Caffeine、Guava 等。
Spring Cache 的核心概念:
Cache
和 CacheManager
。Cache
接口代表具体的缓存对象。它提供了对缓存数据的访问和管理操作,如获取、插入、删除缓存项。CacheManager
是用于管理 Cache
实例的接口。它负责管理多个 Cache
实例,并提供访问这些缓存的机制。使用 Spring Cache 主要是为了简化缓存管理,提高系统性能,并确保缓存的使用对开发者来说是透明和易于维护的。Spring Cache 的主要好处在于它提供了一个简单、透明且统一的缓存管理机制,可以显著提升应用的性能,同时减少了缓存实现的复杂性。它使得开发者能够更专注于业务逻辑,而不用担心底层缓存的细节,并且在系统扩展时,缓存策略也可以灵活调整。下面是使用 Spring Cache 的一些具体好处:
缓存可以显著减少对资源密集型操作的依赖,如数据库查询或复杂计算。通过将频繁访问的结果存储在缓存中,可以减少这些操作的次数,从而提高系统的响应速度和吞吐量。
Spring Cache 提供了统一的缓存管理接口,开发者可以通过简单的注解来实现缓存功能,而不需要直接操作底层缓存框架。
Cache
和 CacheManager
接口,Spring Cache 可以支持多种缓存实现,开发者无需关心底层实现的细节。@Cacheable
、@CachePut
等注解,就可以轻松实现缓存的添加、更新和删除。Spring Cache 使得缓存的使用对业务逻辑透明,开发者不需要修改现有代码逻辑,只需在需要缓存的地方加上注解即可。这种透明性极大地减少了缓存逻辑与业务逻辑的耦合。
Spring Cache 支持多种缓存提供者,如 EhCache、Redis、Caffeine 等,可以根据不同的应用场景选择合适的缓存实现。此外,Spring Cache 还支持缓存的条件控制、缓存键的自定义等高级特性。
condition
和 unless
等属性,开发者可以精确控制缓存的行为,避免不必要的缓存。Spring Cache 与 Spring 生态系统紧密集成,特别是与 Spring Boot 的集成非常方便,使得缓存的配置和管理更加简单。
Spring Cache 支持缓存的自动更新和失效机制,确保缓存数据与实际数据保持一致,避免脏数据的问题。
@CacheEvict
注解可以灵活地控制缓存的失效时间和条件,确保缓存的准确性。通过缓存减少资源的占用,使得应用在负载增加时能更好地扩展。此外,Spring Cache 的抽象层允许开发者轻松切换或扩展缓存策略,而不影响现有的业务逻辑。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.7.3</version>
</dependency>
在SpringCache中提供了很多缓存操作的注解,常见的是以下的几个:
注解 | 说明 |
---|---|
@EnableCaching | 开启缓存注解功能,通常加在启动类上 |
@Cacheable | 在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中 |
@CachePut | 将方法的返回值放到缓存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
在spring boot项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用@EnableCaching
开启缓存支持即可。例如,使用Redis作为缓存技术,只需要导入Spring Data Redis的maven坐标即可。
采用 SpringBoot+SpringCache+Redis+SpringData 实现数据的缓存小例子如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency>
server: port: 8888 spring: datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/spring_cache_demo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true username: **** password: **** redis: host: localhost port: 6379 database: 1 logging: level: com: itheima: mapper: debug service: info controller: info
@EnableCaching
打开cache缓存注解功能@Slf4j
@SpringBootApplication
@EnableCaching // 打开cache缓存注解功能
public class CacheDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CacheDemoApplication.class, args);
log.info("项目启动成功...");
}
}
在启动类中开启缓存注解功能。
作用:用于更新缓存中的数据。与@Cacheable
不同,@CachePut
每次都会调用实际的方法,并将其返回值放入指定的缓存中。
两个参数:
// 当用户ID为1时最终缓存的结果为userCache::1
@PostMapping
@CachePut(value = "userCache", key = "#user.id") // 将返回值自动存入缓存,括号的参数代表的是key的生成定义,userCache::1
public User save(@RequestBody User user) {
userMapper.insert(user);
return user;
}
效果:
附加说明:key 的写法有多种
#user.id : #user指的是方法形参的名称, id指的是user的id属性 , 也就是使用user的id属性作为key ;
#result.id : #result代表方法返回值,该表达式 代表以返回对象的id属性作为key ;
#p0.id:#p0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;
#a0.id:#a0指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数的id属性作为key ;
#root.args[0].id:#root.args[0]指的是方法中的第一个参数,id指的是第一个参数的id属性,也就是使用第一个参数
的id属性作为key ;
作用:用于声明一个方法的返回值是可缓存的。当方法被调用时,Spring Cache会先检查缓存中是否已经存在相应的数据。如果存在,则直接返回缓存中的数据,而无需调用实际的方法。如果不存在,则调用方法并缓存其返回值。
两个重要参数:
/**
* 2、模拟查询请求,首先查找缓存是否存在该数据,没有就查库然后存入缓存,再返回
*/
@GetMapping
@Cacheable(cacheNames = "userCache", key = "#id")
public User getById(Long id) {
User user = userMapper.getById(id);
return user;
}
其他参数:
- value/cacheNames:这两个参数是互斥的,用于指定缓存的名称。你可以使用
value
或cacheNames
来指定缓存的标识符。如果定义了多个缓存名称,则可以使用逗号分隔。Spring 将会根据这个名称去查找对应的 CacheManager 中的 Cache。- key:指定缓存数据时使用的 key,可以是方法参数,也可以是 SpEL 表达式。如果未指定,Spring 将会使用默认的 key 生成策略。
- keyGenerator:用于指定 key 的生成器,当
key
参数不足以满足需求时,可以通过实现org.springframework.cache.interceptor.KeyGenerator
接口来自定义 key 的生成策略。- cacheManager:指定用于解析缓存名称的 CacheManager。如果未指定,将会使用 Spring Boot 自动配置的 CacheManager。
- cacheResolver:当需要动态解析缓存时,可以使用
cacheResolver
。它允许你基于方法的参数或其他条件来选择不同的缓存。- condition:SpEL 表达式,用于指定在什么条件下方法的结果应该被缓存。只有表达式结果为
true
时,才会缓存方法的返回结果。- unless:与
condition
类似,但用于指定在什么条件下方法的结果不应该被缓存。只有当表达式结果为false
时,方法的返回结果才会被缓存。- sync:是否使用同步模式进行缓存。如果设置为
true
,则对于同一个 key 的并发请求,只有一个能够更新缓存,其他请求则会等待缓存更新完成后再从缓存中获取数据。这个参数是 Spring Cache 的扩展,并非所有缓存提供者都支持。
作用:用于从缓存中移除数据。你可以指定根据某个条件来移除缓存中的数据,或者移除整个缓存。
参数:
两种使用方法,适用于清除缓存数据的情况。具体使用见下:
/** * 3、模拟删除某一个数据的请求,同时清理指定的缓存信息 */ @DeleteMapping @CacheEvict(cacheNames = "userCache", key = "#id") // 删除某个具体的key对应的id public void deleteById(Long id) { userMapper.deleteById(id); } /** * 4、模拟批量删除数据请求,同时清理某个类型的key下对应的所有缓存 */ @DeleteMapping("/delAll") @CacheEvict(cacheNames = "userCache", allEntries = true) // 删除userCache下对应的所有缓存 public void deleteAll() { userMapper.deleteAll(); }
@Cacheable
等注解的key
属性来自定义key的生成策略。上述完整项目代码仓库:StrivePeng仓库
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。