Appearance
缓存应用
基本使用
@EnableCaching 开启缓存功能

@Cacheable 触发缓存储存
java
@Cacheable(cacheNames = "users", key = "#user.id")
public User save(User user) {
return user;
}@CacheEvict 触发缓存回收
java
@CacheEvict(cacheNames = "users", key = "#id")
public void delete(int id) {
}@CachePut 更新缓存
java
@CachePut(cacheNames = "users", key = "#user.id")
public User update(User user) {
return user;
}@Caching 组合缓存操作
java
@Caching(evict = {
@CacheEvict(cacheNames = "primary", key = "#p0"), // p0 表示第一个参数
@CacheEvict(cacheNames = "secondary", key = "#id")
})
public void delete(String name, int id) {
}@CacheConfig 类级共享缓存相关设置
高级应用
自定义注解
java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Cacheable(cacheNames = "users", key = "#user.id")
public @interface PackCache {
}
@PackCache
public User save(User user) {
return user;
}切换缓存实现
java
@Configuration
public class CacheConfig {
@Bean
public CacheManager memoryCacheManager() {
return new ConcurrentMapCacheManager(); // 可以指定缓存名称列表
}
@Bean
@Primary
public CacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
// 配置可参考 RedisCache 配置
return RedisCacheManager.builder(connectionFactory).build();
}
}自定义缓存 key 及生成策略
java
@Cacheable(
cacheNames = "users",
key = "T(com.xyg.u1.order.cache.UserKeyGenerator).genKey(#user)", // SPEL
cacheManager = "memoryCacheManager",
keyGenerator = "userKeyGenerator" // 同时声明 key 和 generator, key 被忽略
)
public User save(User user) {
return user;
}
@Component
public class UserKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return target.hashCode() + Arrays.deepToString(params);
}
public String genKey(User user) {
return user.toString();
}
}条件缓存
java
@Cacheable(
cacheNames = "users",
condition = "#user.name != null && #user.name != ''" // name 属性不为空缓存
)
public User save(User user) {
return user;
}根据结果缓存
java
@Cacheable(
cacheNames = "users",
unless = "#result != null" // 结果为 null 不缓存
)
public User save(User user) {
return user;
}删除所有缓存
java
@CacheEvict(
cacheNames = "users",
key = "#id",
allEntries = true // 清除缓存对象里的所有数据,若同时指定 key (key不生效)
)
public void delete(int id) {
}自定义缓存解析器
java
@Component
public class PackCacheResolver implements CacheResolver {
private final CacheManager cacheManager;
public PackCacheResolver(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
// 缓存注解(如 @Cacheable、@CacheEvict)中声明的 cacheNames 或 value 属性
Collection<String> cacheNames = context.getOperation().getCacheNames();
// 如果未配置缓存名称,返回空集合
if (cacheNames == null || cacheNames.isEmpty()) {
return Collections.emptyList();
}
// 遍历缓存名称,从 CacheManager 获取对应的 Cache 实例
Collection<Cache> result = new ArrayList<>(cacheNames.size());
for (String cacheName : cacheNames) {
Cache cache = this.cacheManager.getCache(cacheName);
if (cache == null) {
// todo: 可扩展逻辑(如创建默认缓存或抛异常)
}
result.add(cache); // 将找到的 Cache 加入结果集
}
return result; // 返回所有匹配的 Cache 实例
}
}java
@Cacheable(
cacheNames = "users",
cacheResolver = "packCacheResolver"
)
public User save(User user) {
return user;
}配置
Guava | Caffeine 配置
xml
<!-- Caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
<!-- Guava (可选,Caffeine 性能更优) -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>java
// ---------- Caffeine 配置 ----------
@Bean
public CacheManager caffeineCacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
.initialCapacity(100) // 初始容量
.maximumSize(1000) // 最大缓存数量
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
.recordStats()); // 开启统计
return cacheManager;
}
// ---------- Guava 配置(可选) ----------
@Bean
public CacheManager guavaCacheManager() {
GuavaCacheManager cacheManager = new GuavaCacheManager();
cacheManager.setCacheBuilder(CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES));
return cacheManager;
}Redis Cache 配置
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>
</dependency>java
@Configuration
@EnableCaching // 启用缓存
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
RedisSerializer<Object> valueSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(valueSerializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(valueSerializer);
template.afterPropertiesSet();
return template;
}
// 配置 redis 缓存序列化
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
// GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 携带 @class
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1)) // 设置缓存过期时间为一天
.disableCachingNullValues() // 禁用缓存空值,不缓存null校验
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
new Jackson2JsonRedisSerializer<>(Object.class))); // 设置CacheManager的值序列化方式为json序列化,可加入@Class属性
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build(); // 设置默认的cache组件
}
}更新: 2025-07-20 13:18:58
原文: https://www.yuque.com/lsxxyg/sz/txdnxhs4b4e281gs