
一、缓存的意义
高性能应用系统必然离不开缓存。缓存可以:
- 减少数据库访问频率
- 加速接口响应速度
- 降低系统负载,提升并发能力
Spring 提供了优雅的缓存抽象:Spring Cache,结合 Redis 使用效果最佳。
二、缓存的三种常见模式
模式 | 特点 |
---|---|
读写缓存 | 先查缓存,缓存无命中则查数据库并写入缓存 |
预加载缓存 | 定时任务提前加载数据到缓存 |
延时双删 | 更新数据时先删缓存,延时再删一次防止并发污染 |
三、Spring Cache 快速上手
1. 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2. 启用缓存功能
@SpringBootApplication
@EnableCaching
public class Application {}
四、使用 @Cacheable 缓存查询结果
@Service
public class ProductService {
@Cacheable(value = "product", key = "#id")
public Product getById(Long id) {
System.out.println("访问数据库...");
return productRepository.findById(id).orElse(null);
}
}
第一次调用时会执行方法,结果会缓存到 Redis;后续调用将直接返回缓存。
五、其他缓存注解
注解 | 作用 |
---|---|
@Cacheable | 方法执行前先查缓存,有则跳过执行 |
@CachePut | 方法执行后更新缓存(强制执行) |
@CacheEvict | 清除缓存 |
示例:
@CachePut(value = "product", key = "#product.id")
public Product update(Product product) {
return productRepository.save(product);
}
@CacheEvict(value = "product", key = "#id")
public void delete(Long id) {
productRepository.deleteById(id);
}
六、自定义缓存配置
你可以通过配置文件定义缓存管理器:
spring:
cache:
type: redis
redis:
time-to-live: 3600000 # 毫秒,1小时
或者手动配置:
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.disableCachingNullValues();
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
}
七、避免缓存穿透、击穿、雪崩
1. 缓存穿透(查询永远不存在的数据)
解决:缓存 null 值,加短 TTL。
@Cacheable(value = "product", key = "#id", unless = "#result == null")
2. 缓存击穿(热点 key 突然失效)
解决:加锁 / 本地缓存 / 设置合理过期时间。
3. 缓存雪崩(大量 key 同时过期)
解决:设置随机过期时间,防止同一时间失效。
八、Spring Cache 的局限
- 不支持主动预加载(可以结合定时任务)
- 缓存粒度只能到方法级
- 不适合缓存异步计算结果(推荐用 Guava 或 Caffeine)
九、进阶:使用 RedisTemplate 进行缓存控制
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void manualCache() {
redisTemplate.opsForValue().set("customKey", "value", Duration.ofMinutes(5));
String value = (String) redisTemplate.opsForValue().get("customKey");
}
这种方式适合处理灵活业务逻辑,例如缓存用户 token、短信验证码、排行榜数据等。
十、总结
技术点 | 说明 |
---|---|
Spring Cache | 注解式缓存 |
Redis | 分布式缓存引擎 |
TTL 策略 | 控制缓存生命周期 |
缓存异常处理 | 防止穿透、击穿、雪崩 |
RedisTemplate | 手动缓存操作 |
使用 Spring Cache + Redis,你可以快速将业务服务缓存化,显著提升性能表现。务必结合缓存设计原则合理使用,才能稳定高效支撑大规模访问量。
下一篇将进入 Java 技术栈性能调优相关内容:
《Java 性能调优实践:内存、GC、线程池优化全解析》
是否继续生成第 9 篇?