Naftuli Kay
Naftuli Kay

Reputation: 91740

Getting an EhCache instance with Spring... intelligently

I need to get a specific EhCache instance by name and I'd prefer to autowire if possible. Given the following automatically configured controller, how can I autowire in the cache instance I'm looking for?

@Controller 
public class MyUniqueService {
    ...
}

<beans ...>
    <ctx:component-scan base-package="my.controllers"/>
    <mvc:annotation-driven />
</beans>

How do I configure EhCache in my application context? I don't see any log messages from EhCache about it loading the ehcache.xml file in my /WEB-INF/ directory. How do I make it load it?

How can I integrate EhCache with my Spring application to have it load the ehcache.xml file from my /WEB-INF/ directory and autowire a cache by a given name into my MyUniqueService controller?

Upvotes: 9

Views: 45408

Answers (4)

petrsyn
petrsyn

Reputation: 5116

Assuming you have cacheManager defined:

<bean id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:/ehcache.xml"/>
</bean>

You can get/inject specific cache like this:

@Value("#{cacheManager.getCache('myCacheName')}")
private Cache myCache;

See also examples how to use Spring EL inside the @Value() http://www.mkyong.com/spring3/spring-el-method-invocation-example/ if you are interested.

Upvotes: 17

Bryant Larsen
Bryant Larsen

Reputation: 111

You can also use autowire if the context can find a bean with the correct class. Here is how I configured my xml

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation">
        <value>WEB-INF/ehcache.xml</value>
    </property>
</bean>

<bean id="cache" class="net.sf.ehcache.Cache" factory-bean="cacheManager" factory-method="getCache">
    <constructor-arg value="CacheNameHere" />          
</bean>

And my java class

@Autowired
private net.sf.ehcache.Cache cache;

This setup works for me.

Upvotes: 11

jeha
jeha

Reputation: 10730

First you need to create a Ehcache CacheManager singleton in you app context like this:

<bean id="myEhCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:my-ehcache.xml"/>
</bean>

Here configLocation is set to load from classpath or use value="/WEB-INF/my-ehcache.xml".

In your controller simply inject the CacheManager instance:

@Controller 
public class MyUniqueService {

    @Resource(name="myEhCacheManager")
    private CacheManager cacheManager;

    ...
}

Alternatively, if you'd like to go the "entirely autowired" route, do:

<bean class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager">
        <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
            <property name="configLocation" value="/WEB-INF/ehcache.xml"/>
        </bean>
    </property>
</bean>

Setup your class like so:

@Controller
public class MyUniqueService { 

    @Autowired
    private org.springframework.cache.CacheManager cacheManager;

    public org.springframework.cache.Cache getUniqueObjectCache() {
        return cacheManager.getCache("uniqueObjectCache");
    }
}

uniqueObjectCache corresponds to this cache instance in your ehcache.xml cache definition:

<cache name="uniqueObjectCache"
       maxElementsInMemory="10000"
       eternal="false"
       timeToIdleSeconds="300"
       timeToLiveSeconds="600"
       memoryStoreEvictionPolicy="LRU"
       transactionalMode="off"/>

There isn't a way to inject an actual cache instance, but as shown above, you can inject a cache manager and use it to get the cache you're interested in.

Upvotes: 17

Vincent Devillers
Vincent Devillers

Reputation: 1628

Indeed! Or if you want to use a java config class:

        @Inject
        private ResourceLoader resourceLoader;

        @Bean
        public CacheManager cacheManager() {
            EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
            try {
                ehCacheCacheManager.setCacheManager(ehcacheCacheManager().getObject());
            } catch (Exception e) {
                throw new IllegalStateException("Failed to create an EhCacheManagerFactoryBean", e);
            }
            return ehCacheCacheManager;
        }

        @Bean
        public FactoryBean<net.sf.ehcache.CacheManager> ehcacheCacheManager() {
            EhCacheManagerFactoryBean bean = new EhCacheManagerFactoryBean();
            bean.setConfigLocation(resourceLoader.getResource("classpath:ehcache.xml"));
            return bean;
        }

Upvotes: 9

Related Questions