Search code examples
springspring-mvcspring-bootguavagoogle-guava-cache

How to refresh the key and value in cache after they are expired in Guava (Spring)


So, I was looking at caching methods in Java (Spring). And Guava looked like it would solve the purpose.

This is the usecase -

I query for some data from a remote service. Kind of configuration field for my application. This field will be used by every inbound request to my application. And it would be expensive to call the remote service everytime as it's kind of constant which changes periodically.

So, on the first request inbound to my application, when I call remote service, I would cache the value. I set an expiry time of this cache as 30 mins. After 30 mins when the cache is expired and there is a request to retrieve the key, I would like a callback or something to do the operation of calling the remote service and setting the cache and return the value for that key.

How can I do it in Guava cache?


Solution

  • Here i give a example how to use guava cache. If you want to handle removal listener then need to call cleanUp. Here i run a thread which one call clean up every 30 minutes.

    import com.google.common.cache.*;
    import org.springframework.stereotype.Component;
    
    
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    @Component
    public class Cache {
    
    public static LoadingCache<String, String> REQUIRED_CACHE;
    
    public Cache(){
        RemovalListener<String,String> REMOVAL_LISTENER = new RemovalListener<String, String>() {
            @Override
            public void onRemoval(RemovalNotification<String, String> notification) {
                if(notification.getCause() == RemovalCause.EXPIRED){
                    //do as per your requirement
                }
            }
        };
    
        CacheLoader<String,String> LOADER = new CacheLoader<String, String>() {
            @Override
            public String load(String key) throws Exception {
                return null; // return as per your requirement. if key value is not found
            }
        };
    
        REQUIRED_CACHE = CacheBuilder.newBuilder().maximumSize(100000000)
                .expireAfterWrite(30, TimeUnit.MINUTES)
                .removalListener(REMOVAL_LISTENER)
                .build(LOADER);
    
        Executors.newSingleThreadExecutor().submit(()->{
            while (true) {
                REQUIRED_CACHE.cleanUp(); // need to call clean up for removal listener
                TimeUnit.MINUTES.sleep(30L);
            }
        });
    }
    }
    

    put & get data:

    Cache.REQUIRED_CACHE.get("key");
    Cache.REQUIRED_CACHE.put("key","value");