1

我正在尝试使用 Spring @Cacheable 注释。

 @Cacheable(value="users")          
public List<User> findAll() {
    System.out.println("Looking for All users : ");
    return userRepository.findAll();
}

@Override
@Cacheable(value="users")  
public User findOne(String userId) {
    System.out.println("Looking for user : "+ userId);
    return userRepository.findById(userId).get();
}

当我执行第一个方法时List<User>,我得到:

  • 第一次:从数据库中选择所有字段
  • 第二次:从缓存中选择所有字段
  • 第三次:从缓存中选择所有字段

到目前为止,这很好。

当我执行第二种方法时findOne(String userId),我得到的结果来自:

  • 第一次:从数据库中选择特定字段
  • 第二次:从缓存中选择特定字段
  • 第三次:从缓存中选择特定字段

这又是好事。

当我执行第一个方法时List<User>,我得到:

从缓存中选择所有字段数据

问题:两种方法(List<User>并且findOne(String userId)具有相同的缓存名称但它们返回不同的结果。

4

1 回答 1

1

当您使用注解对您的方法进行@Cacheable注解时,Spring 将对其应用缓存行为。缓存名称用于对同一缓存区域中的缓存数据进行分组。但是为了将值存储在缓存区域中,Spring 会生成缓存键。

默认情况下,SimpleKeyGenerator用于在缓存中生成键值。SimpleKeyGenerator使用方法参数生成缓存键。键值将使用SimpleKey对象包装。

因此,在您的情况下,它将执行以下操作:

第一次调用- 缓存中没有数据

  • List<User> findAll()

    1. 无参数
    2. 关键=SimpleKey.EMPTY
    3. 使用键存储方法导致缓存
  • User findOne(String userId)

    1. userId范围
    2. 关键=new SimpleKey(userId)
    3. 使用键存储方法导致缓存

如上所示,虽然@Cacheable在这两种情况下您的缓存名称相同,但用于存储方法结果的键是不同的。当您再次调用您的方法时:

第二次调用- 缓存中的数据

  • List<User> findAll()

    1. 无参数
    2. 关键=SimpleKey.EMPTY
    3. 使用键从缓存中获取结果
  • User findOne(String userId)

    1. userId范围
    2. 关键=new SimpleKey(userId)
    3. 使用键从缓存中获取结果
于 2018-10-24T09:11:48.320 回答