缓存是提升应用性能的常用手段。它通过将耗时的操作结果存储起来,下次请求可以直接从缓存中获取,从而避免重复计算或查询数据库,显著减少响应时间和服务器负载。Spring 框架提供了强大的缓存抽象 Spring Cache,它简化了缓存的使用,并提供了与多种缓存技术的集成。
Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如:
- EHCache
- Caffeine
- Redis(常用)
一、Spring Cache 核心概念
Spring Cache 基于 AOP(面向切面编程)实现,其核心思想是将缓存逻辑与业务逻辑分离,通过注解或 XML 配置的方式声明缓存行为。主要组件包括:
-
@Cacheable: 触发缓存逻辑。如果缓存中有数据,则直接返回;否则执行方法并将结果放入缓存。
-
@CachePut: 无论缓存中是否存在数据,都会执行方法并将结果更新到缓存。适用于更新缓存的场景。
-
@CacheEvict: 从缓存中移除数据。可以根据 key 或条件移除指定的数据,也可以清空整个缓存。
-
@Caching: 组合多个缓存操作,例如同时使用 @Cacheable 和 @CacheEvict。
-
Cache 接口: 定义了缓存的基本操作,例如 get、put、evict 等。
-
CacheManager 接口: 管理 Cache 实例,例如创建、获取、销毁缓存。
-
缓存提供者: Spring Cache 支持多种缓存实现,如 Ehcache、Redis(常用)、Caffeine 等。
二、Spring Boot 中使用 Spring Cache
1.添加依赖至pom.xml:
<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> <!- or other cache provider -->
</dependency>
这段代码添加了 Spring Boot 的缓存 starter 和 Redis starter。 你可以根据需要替换成其他缓存提供者,例如 Caffeine 或 Ehcache。
2.启用缓存:
在 Spring Boot 应用的入口类上添加 @EnableCaching 注解:
@SpringBootApplication
@EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@EnableCaching 注解启用 Spring Cache 功能,使 Spring 可以扫描并处理缓存相关的注解。
3.配置缓存:
可以使用 application.properties 或 application.yml 配置缓存,例如使用 Redis 作为缓存提供者:
spring:
cache:
type: redis
redis:
host: localhost
port: 6379
* 这段配置指定了使用 Redis 作为缓存,并配置了 Redis 的连接信息。
4.使用缓存注解:
@Service
public class UserService {
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
System.out.println("Fetching user from database...");
// Simulate database query
return new User(id, "User " + id);
}
// `@Cacheable` 注解会尝试从名为 "users" 的缓存中获取 key 为 id 的数据。如果缓存命中,则直接返回缓存中的值;否则执行方法体,并将返回值缓存起来。
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
System.out.println("Updating user in database...");
// Simulate database update
return user;
}
// `@CachePut` 注解会强制执行方法体,并将返回值更新到名为 "users" 的缓存中,key 为 user 的 id。 这通常用于更新缓存数据。
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
System.out.println("Deleting user from database...");
// Simulate database delete
}
// `@CacheEvict` 注解会从名为 "users" 的缓存中移除 key 为 id 的数据。 这通常用于删除缓存数据。
@Caching(evict = {
@CacheEvict(value = "users", key = "#id"),
@CacheEvict(value = "users", allEntries = true)
})
public void deleteUserAndClearCache(Long id) {
System.out.println("Deleting user from database and clearing cache...");
// Simulate database delete
}
// `@Caching` 注解可以组合多个缓存操作。这里组合了两个 `@CacheEvict` 操作,先删除指定 id 的用户数据,然后清空整个 "users" 缓存。
}
以上代码演示了如何使用 @Cacheable、@CachePut 和 @CacheEvict 注解,并对每个方法的代码进行了详细解释。
-
getUserById 方法使用了 @Cacheable,第一次调用会执行方法体并缓存结果,后续调用相同 id 的用户会直接从缓存中获取。
-
updateUser 方法使用了 @CachePut,每次调用都会执行方法体并更新缓存。
-
deleteUser 方法使用了 @CacheEvict,根据 id 删除缓存中的用户数据。
-
deleteUserAndClearCache 方法使用了 @Caching 组合了两个 @CacheEvict 操作,删除指定用户并清空整个缓存。
三、进阶用法
-
unless 和 condition 属性: 可以根据方法返回值或参数控制是否缓存或驱逐缓存。例如 unless = "#result == null" 表示如果返回值为 null 则不缓存。
-
keyGenerator 属性: 自定义缓存 key 的生成策略。
-
cacheManager 属性: 指定使用的 CacheManager。
-
cacheResolver 属性: 动态选择使用的 Cache。
四、总结
Spring Cache 提供了一种简单而强大的缓存机制,可以显著提升 Spring Boot 应用的性能。通过合理使用缓存注解和配置,可以有效减少数据库访问和计算量,提升用户体验。本文介绍了 Spring Cache 的核心概念、使用方法和进阶用法,并对示例代码进行了详细解释,希望能够帮助读者更好地理解和应用 Spring Cache. 记住根据你的具体需求选择合适的缓存提供者和配置. 例如,对于高并发场景,Caffeine 通常是比 Redis 更好的本地缓存选择. 对于分布式应用,Redis 则更合适. 并且要注意缓存 key 的设计,避免 key 冲突和缓存雪崩等问题。感谢各位看官的观看,谢谢~