Tuesday, June 3, 2008

OSCache + Spring Framework

Since I didn't find a good reference to using OSCache with Spring after browsing the web for a day or so I thought that it would be useful to have this posted.

This example uses source level metadata (JDK 5.0 annotation) to tag methods as cacheable and configure the refreshPeriod for a particular OSCache's cache group (it's the same concept as cache region when using OSCache with Hibernate).

We first tag the methods with annotations:
@Cacheable(modelId = "testCaching")
public List<Listing> getListings() {
// some implementation
}

@Cacheable(modelId = "testFlushing")
public void saveListings(List<Listing> listing) {
// some implementation
}

And then we add the following to the application-context.xml for Spring:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!-- Domain -->
<bean id="listingRepositoryXmlImpl"
class="com.myco.service.ListingRepositoryXmlImpl"/>

<!-- Cache Setup -->
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />

<!--
The created cache manager is a singleton instance of
com.opensymphony.oscache.general.GeneralCacheAdministrator
-->
<bean id="cacheManager"
class="org.springmodules.cache.provider.oscache.OsCacheManagerFactoryBean">
<!-- Optional properties -->
<property name="configLocation"
value="classpath:oscache.properties" />
</bean>

<bean id="cacheProviderFacade"
class="org.springmodules.cache.provider.oscache.OsCacheFacade">
<property name="cacheManager" ref="cacheManager" />
</bean>

<!-- Cache-feature Weaving -->
<bean id="cachingAttributeSource"
class="org.springmodules.cache.annotations.AnnotationCachingAttributeSource">
</bean>

<bean id="cachingInterceptor"
class="org.springmodules.cache.interceptor.caching.MetadataCachingInterceptor">
<property name="cacheProviderFacade" ref="cacheProviderFacade" />
<property name="cachingAttributeSource"
ref="cachingAttributeSource" />
<property name="cachingListeners">
<list>
<!-- We don't have any listener for now
<ref bean="cachingListener" />
-->
</list>
</property>
<property name="cachingModels">
<props>
<!--
Bean properties are set here for the underlying CachingModel implementation (OsCacheCachingModel).
Here we are setting the "group" and "refreshPeriod".
Note that the PropertyEditor will translate the semicolon separated key-values into a java.util.Map
-->

<prop key="testCaching"><!-- Here we map the modelId "testCaching" (Spring) to group "testCache" (OSCache), we also set the refresh period -->
groups=testCache;refreshPeriod=5
</prop>
</props>
</property>
</bean>

<bean id="cachingAttributeSourceAdvisor"
class="org.springmodules.cache.interceptor.caching.CachingAttributeSourceAdvisor">
<constructor-arg ref="cachingInterceptor" />
</bean>

<bean id="flushingAttributeSource"
class="org.springmodules.cache.annotations.AnnotationFlushingAttributeSource">
</bean>

<bean id="flushingInterceptor"
class="org.springmodules.cache.interceptor.flush.MetadataFlushingInterceptor">
<property name="cacheProviderFacade" ref="cacheProviderFacade" />
<property name="flushingAttributeSource"
ref="flushingAttributeSource" />
<property name="flushingModels">
<props>
<!-- Refresh period is set here for the underlying CachingModel implementation (OsCacheCachingModel) -->

<prop key="testFlushing"><!-- Here we map the modelId "testFlushing" (Spring) to group "testCache" (OSCache) -->
groups=testCache
</prop>
</props>
</property>
</bean>

<bean id="flushingAttributeSourceAdvisor"
class="org.springmodules.cache.interceptor.flush.FlushingAttributeSourceAdvisor">
<constructor-arg ref="flushingInterceptor" />
</bean>

</beans>

And that's all there is to it. Happy caching!

No comments: