我有两种方法,第一种返回元素列表,第二种返回单个元素:
List<User> getUsersFromExternalSystem(List<Integer> userIds);
User getUserFromExternalSystem(Integer userId);
我希望 Spring 缓存这两个方法的结果,这样当调用元素列表方法 (getUsersFromExternalSystem()
) 时,它会缓存提供的 ids ( userIds
),当使用之前提供给元素列表方法的 id 调用单个元素方法 (getUserFromExternalSystem()
) 时,它使用缓存。
我可以简单地将 @Cacheable
应用于这些方法,然后(如果我理解正确的话)当我调用时:
getUsersFromExternalSystem(Arrays.asList(1, 2))
结果将被缓存但是当我调用时
getUserFromExternalSystem(1);
缓存不会被使用。这在 Spring 中如何完成?
最佳答案
您可以使用以下方法。只有第一个方法 getUser(Integer id)
是可缓存的,第二个方法只是组合 getUser
调用的结果。
@Service
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
class UserService {
private final UserService self;
@Autowired
public UserService(UserService userService) {
self = userService;
}
@Cacheable(cacheNames = "users", key = "id") // assuming that you've already initialized Cache named "users"
public User getUser(Integer id) {
return new User(); // ... or call to some DataSource
}
public List<User> getUsers(List<Integer> ids) {
List<User> list = new ArrayList<>();
for (Integer id : ids) {
list.add(self.getUser(id));
}
return list;
}
}
将bean注入(inject)自己并调用的技巧
self.getUser(id)
而不是 this.getUser(id)
是必需的,因为 @Cacheable
只有在 Spring 代理 bean 上使用时才会实际调用,而 this
不是代理。更多细节在这里 Transactions, Caching and AOP: understanding proxy usage in Spring
关于java - 在 Spring 中将两个方法的结果缓存在一个缓存中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58763234/