Caching method result in Spring with Ehcache

An example of caching the result of a method.

Enable cache for SpringBoot application

@Configuration
@EnableCaching
public class CacheConfig {
}

Configure caching options

Create and save a file named ’ehcache3.xml’ in the application resources folder.

<config
        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xmlns='http://www.ehcache.org/v3'
        xsi:schemaLocation="
        http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">

    <cache alias="catalog">
        <key-type>java.lang.String</key-type>
        <value-type>com.example.model.Catalog</value-type>
        <expiry>
            <ttl unit="seconds">120</ttl>
        </expiry>
        <resources>
            <heap unit="entries">2</heap>
        </resources>
    </cache>

</config>

Configuring caching options in the application.yml

spring:
  cache:
    jcache:
      config: classpath:ehcache3.xml

Create a custom key generator

For an example we want to have caches of catalogs for each languages.

import org.springframework.cache.interceptor.KeyGenerator
import org.springframework.context.i18n.LocaleContextHolder
import java.lang.reflect.Method

class CatalogKeyGenerator: KeyGenerator {

    override fun generate(target: Any, method: Method, vararg params: Any?): Any {
        return LocaleContextHolder.getLocale().language
    }
}

Define bean for a custom key generator

@Configuration
@EnableCaching
class EhcacheConfig {

    @Bean
    fun catalogKeyGenerator(): KeyGenerator? = CatalogKeyGenerator()
}

Annotate service method

@Service
class CatalogServiceImpl: CatalogService {

    @Cacheable(cacheNames = ["catalog"], keyGenerator = "catalogKeyGenerator")
    override fun catalog(): Catalog {
        logger.debug("Catalog generation called")
        val catalog = TODO() // generate a cache for the current language
        return catalog
    }
    
}