11

Following the spring documentation about cache I could use cache on my project, but how can I configure guava to define a expired time or size per cache name?

applicationConfig.xml

<bean id="cacheManager" class="org.springframework.cache.guava.GuavaCacheManager"/>

Foo.java

@Cacheable(value="courses", key="#user.id")
public List<Course> getCoursesByUser(User user) {
    ...
}
xedo
  • 1,117
  • 3
  • 18
  • 34

5 Answers5

30

You can configure caches separately. See Spring Guava cache

@Bean
public CacheManager cacheManager() {
    SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
    GuavaCache bookCache = new GuavaCache("book", CacheBuilder.newBuilder().build());
    GuavaCache booksExpirableCache = new GuavaCache("books", CacheBuilder.newBuilder()
            .expireAfterAccess(30, TimeUnit.MINUTES)
            .build());
    simpleCacheManager.setCaches(Arrays.asList(bookCache, booksExpirableCache));
    return simpleCacheManager;
}
Kyrylo Semenko
  • 866
  • 9
  • 11
17

You can specify CacheBuilder for your GuavaCacheManager in your Spring configuration

  1. In case of Java configuration it can look like this:
@Bean
public CacheManager cacheManager() {
    GuavaCacheManager cacheManager = new GuavaCacheManager();
    cacheManager.setCacheBuilder(
        CacheBuilder.
        newBuilder().
        expireAfterWrite(2, TimeUnit.SECONDS).
        maximumSize(100));
    return cacheManager;
}
  1. In case of XML configuration, you can use CacheBuilderSpec in guava
<bean id="legendaryCacheBuilder"
      class="com.google.common.cache.CacheBuilder"
      factory-method="from">
    <constructor-arg value="maximumSize=42,expireAfterAccess=10m,expireAfterWrite=1h" />
</bean>

For more information look at:

http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/cache/CacheBuilderSpec.html

Injecting Google guava cache builder into bean via Spring

Community
  • 1
  • 1
mavarazy
  • 7,562
  • 1
  • 34
  • 60
  • 1
    this is a global configuration, is it possible set it by cache name? – xedo Feb 03 '15 at 11:38
  • I'm not sure what you mean by global configurations, you can make them as local as you want :) – mavarazy Feb 03 '15 at 12:23
  • for instance the cache value `courses` expires on 10min but the value `foo` expire on 5h – xedo Feb 03 '15 at 16:17
  • 1
    If you want to expire based on keys, I'm not aware of such functionality in guava. If you want to have few Guava caches in running system, it's another thing - take a look at http://java.dzone.com/articles/spring-caching-abstraction-and – mavarazy Feb 03 '15 at 17:42
  • 2
    You could make a separate cacheManager with a different cacheBuilder that has a different configuration. Then specify `@Cacheable(value="courses", cacheManager="shortTTLCacheManager")` and `@Cacheable(value="foo", cacheManager="longTTLCacheManager")` – skelly Jun 17 '15 at 18:14
  • Can some suggest how to use `CacheBuilderSpec` instead of hard coding `expireAfterWrite(2, TimeUnit.SECONDS)`. Gone through speck and property `expireAfterWrite=2s`, but not sure, how to use the same in this context. – Paramesh Korrakuti Jul 17 '15 at 14:48
2

In another way

XML

   <bean id="cacheManager" class="org.springframework.cache.guava.GuavaCacheManager">
        <property name="cacheBuilderSpec">
            <bean class="com.google.common.cache.CacheBuilderSpec" factory-method="parse">
                <constructor-arg name="cacheBuilderSpecification" value="expireAfterWrite=55m"/>
            </bean>
        </property>
    </bean>

Java

@Cacheable(value = "tokenValue", cacheManager = "cacheManager")
Jaikrat
  • 1,124
  • 3
  • 24
  • 45
1

I think that @mavarazy answer is the best. I only add if you need you own automatic missed cache configuration you could do it on the following way.

First define you own cache manager which creates automatically cache if you need it:

public class MyCacheManager extends SimpleCacheManager {

    @Override
    protected Cache getMissingCache(String name) {
        // or different cache config if you need
        return new GuavaCache(name, CacheBuilder.newBuilder().maximumSize(250).expireAfterWrite(10, TimeUnit.MINUTES).build());
    }
}

And now you can define cache manager configuration:

@Bean
public CacheManager cacheManager() {
    SimpleCacheManager simpleCacheManager = new MyCacheManager();
    GuavaCache specificCacheConfig = new GuavaCache("specificCacheConfigName",
        CacheBuilder.newBuilder().expireAfterAccess(60, TimeUnit.MINUTES).build());
    simpleCacheManager.setCaches(Collections.singletonList(specificCacheConfig));
    return simpleCacheManager;
}
Przemek Nowak
  • 7,173
  • 3
  • 53
  • 57
0

By extending 'CachingConfigurerSupport' class, you can provide custom cache definition.

For example,

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
    @Bean
    @Override
    public CacheManager cacheManager() {
    
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        GuavaCache myOrgCache = new GuavaCache("myOrgCache", CacheBuilder.newBuilder().build());
        GuavaCache myEmployeeCache = new GuavaCache("myEmployeeCache",
                CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build());
        cacheManager.setCaches(Arrays.asList(myOrgCache, myEmployeeCache));
        return cacheManager;
    }

    @Override
    public KeyGenerator keyGenerator() {
        return new CacheKeyGenerator();
    }
}

Reference link.

Hari Krishna
  • 3,658
  • 1
  • 36
  • 57