4

I have this method that loads a lot of data from the database

private List<Something> loadFromDb() {
    //some loading which can take a lot of time
}

I am looking for a simple way to cache the results for some fixed time (2 minutes for example). I do not need to intercept the method invocation itself, just to cache the returned data - I can write another method that does the caching if necessary.

I don't want to:

  • Use AOP compile time weaving like this one - it requires changes in the build
  • Use @Cacheable in Spring - I have to define a cache for each cacheable method

Is there a library which can simplify this task, or should I do something else? An example use of such library would be

private List<Something> loadFromDbCached() {
    //in java 8 'this::loadFromDb' would be possible instead of a String
    return SimpleCaching.cache(this, "loadFromDb", 2, MINUTES).call();
}

EDIT: I am looking for a library that does that, managing the cache is more trouble than it seems, especially if you have concurrent access

4

3 回答 3

13

Use Guava's Suppliers.memoizeWithExpiration(Supplier delegate, long duration, TimeUnit unit):

private final Supplier<List<Something>> cache =
    Suppliers.memoizeWithExpiration(new Supplier<List<Something>>() {
        public List<Something> get() {
            return loadFromDb();
        }
    }, 2, MINUTES);

private List<Something> loadFromDbCached() {
    return cache.get();
}
于 2013-06-13T13:56:49.313 回答
7

Check Guava Cache Builder It may be useful.

于 2013-06-13T13:55:01.247 回答
3

You can use @Cacheable annotation from jcabi-aspects:

public class Resource {
  @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS)
  public String load(URL url) {
    return url.openConnection().getContent();
  }
}

The result of load() will be cached for five seconds. Check this article, it explains the details: http://www.yegor256.com/2014/08/03/cacheable-java-annotation.html

于 2014-08-04T07:09:31.807 回答