简体   繁体   中英

Cache the results of two methods in a single cache in Spring

I have two methods, the first returning a list of elements and the second returning a single element:

List<User> getUsersFromExternalSystem(List<Integer> userIds);
User getUserFromExternalSystem(Integer userId);

I would like Spring to cache the results of these two methods, so that when the list of elements method ( getUsersFromExternalSystem() ) is called it caches the results for the provided ids ( userIds ) and when the single element method ( getUserFromExternalSystem() ) is called with the id previously provided to the list of elements method it uses the cache.

I can simply apply @Cacheable to these methods, then (if I understand correctly) when I call:

getUsersFromExternalSystem(Arrays.asList(1, 2))

the results will be cached but when I call

getUserFromExternalSystem(1);

the cache will not be used. How this be done in Spring?

You can use following approach. Only first method getUser(Integer id) is cacheable, and second method just combines the results of getUser invocations.

@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;
    }
}

The trick with injecting a bean into himself and calling

self.getUser(id) instead of this.getUser(id)

is required because @Cacheable will be actually invoked only when used on a Spring proxied bean, and this is not a proxy. More details here Transactions, Caching and AOP: understanding proxy usage in Spring

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM