面试题:Spring 中的 @Cacheable 和 @CacheEvict 注解的作用是什么?

@CacheableCacheEvict 是 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") 时,会直接从缓存中返回结果,而不会执行方法体。

常用属性

  • valuecacheNames:指定缓存的名称(可以指定多个缓存)。
  • 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 的缓存数据。

常用属性

  • valuecacheNames:指定缓存的名称(可以指定多个缓存)。
  • 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
点赞12 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容