Beyond Redis: When to Choose EhCache for Java In‑Process Caching
With hardware costs dropping, many default to Redis for caching, but it isn’t always optimal; this article examines EhCache—a pure‑Java, in‑process cache—covering its architecture, eviction policies, API and XML configurations, and step‑by‑step Spring Boot integration, helping you decide when to prefer it.
Background
As hardware becomes cheaper, developers often rely on adding more machines instead of optimizing code, leading to a default choice of Redis for caching. However, Redis is not always the most efficient solution, especially for single‑process, high‑throughput scenarios.
What Is EhCache?
EhCache is a pure‑Java, in‑process caching framework that operates directly inside the JVM, offering fast, lightweight caching. It is the default cache provider for Hibernate and is supported by Spring Boot through Spring’s cache abstraction.
Key Features
Simple and fast with multiple caching strategies.
Two‑level storage: memory and disk, alleviating capacity concerns.
Disk persistence writes cache data during JVM shutdown.
Supports distributed caching via RMI, JGroups, JMS, or Cache Server.
Provides listener interfaces for cache and cache manager events.
Allows multiple cache manager instances and multiple cache regions per instance.
Advantages and Limitations
Advantages include low latency due to in‑process operation and ease of use. Limitations are significant disk usage for the DiskCache tier and lack of strong data safety guarantees; abrupt JVM termination can cause conflicts, and cache rebuilding may be required.
EhCache vs. Redis
EhCache operates within the JVM, offering higher speed for single‑node applications, while Redis accesses a separate service over sockets, providing better support for distributed clusters and larger cache sizes. Choose EhCache for monolithic, high‑frequency access scenarios; choose Redis for large, shared, or distributed caches.
Architecture Overview
The core components are CacheManager, Cache, and Element. CacheManager creates and manages caches; each Cache holds multiple Elements, which are the actual cached entries.
Cache replication, in‑process APIs, and network APIs provide mechanisms for distributed caching, JSR/JMX compatibility, and RESTful/JMS access respectively.
Eviction Strategies
EhCache supports three eviction algorithms:
FIFO – removes the oldest entries first.
LRU – removes the least recently used entries.
LFU – removes the least frequently used entries.
It uses a lazy eviction mechanism, storing timestamps with each entry and checking TTL on reads.
Practical Usage
API‑Based Configuration
Add the Maven dependency:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.6</version>
</dependency>Example Java test class:
public class EhCacheTest {
@Test
public void test() {
// 1. Build a CacheManager
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("preConfigured",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.heap(100)).build())
.build(true);
Cache<Long, String> preConfigured = cacheManager.getCache("preConfigured", Long.class, String.class);
System.out.println("Pre‑configured cache: " + preConfigured);
// 2. Create a new cache
Cache<Long, String> myCache = cacheManager.createCache("myCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.heap(100)).build());
myCache.put(1L, "da one!");
String value = myCache.get(1L);
System.out.println("Value for key 1L: " + value);
cacheManager.close();
}
}XML‑Based Configuration
Place ehcache.xml under src/main/resources:
<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.xsd'>
<cache alias="foo">
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<resources>
<heap unit="entries">20</heap>
<offheap unit="MB">10</offheap>
</resources>
</cache>
<cache-template name="myDefaults">
<key-type>java.lang.Long</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">200</heap>
</cache-template>
<cache alias="bar" uses-template="myDefaults">
<key-type>java.lang.Number</key-type>
</cache>
<cache alias="simpleCache" uses-template="myDefaults"/>The XML defines a regular cache, a template for reuse, and a cache that inherits the template while overriding the key type.
Spring Boot Integration
Add the starter and EhCache dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.6</version>
</dependency>Configure the cache location in application.properties: spring.cache.ehcache.config=ehcache.xml Enable caching in the main class:
@EnableCaching
@SpringBootApplication
public class SpringBootMainApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootMainApplication.class, args);
}
}Define a cached entity:
@Data
public class Person {
private int id;
private String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
}Service interface and implementation using @Cacheable:
public interface PersonService {
Person getById(int id);
}
@Service("personService")
public class PersonServiceImpl implements PersonService {
@Cacheable(value = "personCache", key = "#id")
@Override
public Person getById(int id) {
if (id == 1) return new Person(1, "Tom");
else if (id == 2) return new Person(2, "Jim");
return new Person(3, "Other");
}
}Unit test demonstrating cache hits:
@SpringBootTest
class PersonServiceTest {
@Resource
private PersonService personService;
@Test
void testCache() throws InterruptedException {
personService.getById(1); // first call, hits method
personService.getById(1); // second call, served from cache
}
}Log output shows the method is invoked only once, confirming caching works.
Conclusion
The article provides an entry‑level guide to EhCache, covering its concepts, eviction policies, API and XML configuration, and Spring Boot integration. While EhCache excels in single‑process, high‑throughput scenarios, it lacks robust distributed features, so for large‑scale or clustered environments Redis remains preferable.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Senior Brother's Insights
A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
