@Cacheable
和 CacheEvict
是 Spring 框架中用于缓存管理的注解,它们基于 Spring 的缓存抽象机制,可以帮助开发者轻松实现方法的缓存和缓存清理功能。
1. @Cacheable
注解
@Cacheable
用于将方法的返回值缓存起来,当下次调用相同的方法时,如果缓存中存在对应的结果,则直接返回缓存中的数据,而不再执行方法体。
作用
- 将方法的返回值缓存到指定的缓存中。
- 当方法再次被调用时,如果缓存命中,则直接返回缓存结果,避免重复计算或查询。
使用场景
- 适合用于读多写少的场景,例如查询数据库、调用外部接口等耗时操作。
- 可以显著提升性能,减少重复计算或查询的开销。
示例
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Cacheable(value = "myCache", key = "#id") // 将返回值缓存到名为 "myCache" 的缓存中,key 为方法的参数 id
public String getDataById(String id) {
// 模拟耗时操作
System.out.println("Fetching data from database for id: " + id);
return "Data for " + id;
}
}
在这个例子中:
- 第一次调用
getDataById("1")
时,会执行方法体并将结果缓存到myCache
中,key 为1
。 - 第二次调用
getDataById("1")
时,会直接从缓存中返回结果,而不会执行方法体。
常用属性
value
或cacheNames
:指定缓存的名称(可以指定多个缓存)。key
:指定缓存的 key,支持 SpEL 表达式。condition
:指定条件,只有当条件为true
时才会缓存。unless
:指定条件,当条件为true
时不会缓存。
2. @CacheEvict
注解
@CacheEvict
用于清除缓存,当某个方法执行后,可以清除指定的缓存数据,以确保缓存中的数据与底层数据源保持一致。
作用
- 清除指定的缓存数据。
- 通常在更新或删除操作后使用,避免缓存中的数据与数据库不一致。
使用场景
- 适合用于写操作(如更新、删除)后清理缓存。
- 可以避免脏数据问题,确保缓存的一致性。
示例
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@CacheEvict(value = "myCache", key = "#id") // 清除名为 "myCache" 的缓存中 key 为 id 的数据
public void updateDataById(String id, String newData) {
// 模拟更新操作
System.out.println("Updating data for id: " + id);
}
}
在这个例子中:
- 当调用
updateDataById("1", "New Data")
时,会清除myCache
中 key 为1
的缓存数据。
常用属性
value
或cacheNames
:指定缓存的名称(可以指定多个缓存)。key
:指定要清除的缓存的 key,支持 SpEL 表达式。allEntries
:是否清除缓存中的所有数据,默认为false
。beforeInvocation
:是否在方法执行前清除缓存,默认为false
(方法执行成功后清除缓存)。
3. @Cacheable
和 @CacheEvict
的结合使用
在实际开发中,@Cacheable
和 @CacheEvict
通常会结合使用,以实现缓存的读写一致性。
示例
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Cacheable(value = "myCache", key = "#id")
public String getDataById(String id) {
System.out.println("Fetching data from database for id: " + id);
return "Data for " + id;
}
@CacheEvict(value = "myCache", key = "#id")
public void updateDataById(String id, String newData) {
System.out.println("Updating data for id: " + id);
}
}
在这个例子中:
getDataById
方法用于查询数据并缓存结果。updateDataById
方法用于更新数据并清除缓存,确保下次查询时获取最新的数据。
4. 总结
@Cacheable
:用于缓存方法的返回值,适合读多写少的场景,提升性能。@CacheEvict
:用于清除缓存数据,适合写操作后清理缓存,确保数据一致性。- 两者结合使用可以实现高效的缓存管理,避免脏数据问题,同时提升系统性能。
在实际开发中,合理使用缓存可以显著提升系统性能,但需要注意缓存的一致性和失效策略,避免出现脏数据或缓存穿透等问题。
THE END
暂无评论内容