Showing posts with label ehcache. Show all posts
Showing posts with label ehcache. Show all posts

Thursday, 30 June 2022

Spring boot: ehcache: Receive cache events by implementing CacheEventListener

In this post, I am going to explain how to get the cache events by implementing CacheEventListener.

 

Supported event types

org.ehcache.event.EventType enum define below event types.

 

a.   EVICTED : Represents a cache entry being evicted

b.   EXPIRED : Represents a cache entry being expired

c.    REMOVED : Represents a cache entry being removed

d.   CREATED : Represents a cache entry being created

e.   UPDATED : Represents a cache entry being updated

 

Supported event firing modes

org.ehcache.event.EventFiring enum defines below event firing modes.

 

a.   ASYNCHRONOUS: Events will fire asynchronously. The mutating thread does not have to wait for firing to complete.

b.   SYNCHRONOUS: Events will fire synchronously. The mutating thread will wait for firing to complete.

 

Supported event ordering modes

org.ehcache.event.EventOrdering define below event ordering modes.

a.   UNORDERED: Events may be observed out of order.

b.   ORDERED: Ordering of events is guaranteed on a per-key basis.

 

Let’s define custom cache event listener by implementing CacheEventListener interface.

public class MyCacheEnventListener implements CacheEventListener<Object, Object> {
	private static final Logger LOGGER = LoggerFactory.getLogger(MyCacheEnventListener.class);

	public void onEvent(CacheEvent<? extends Object, ? extends Object> cacheEvent) {
		LOGGER.info("\n-----------------------------------------------");
		LOGGER.info("Event received");
		LOGGER.info("event type: {}", cacheEvent.getType());
		LOGGER.info("event key: {}", cacheEvent.getKey());
		LOGGER.info("old value: {}", cacheEvent.getOldValue());
		LOGGER.info("new value: {}", cacheEvent.getNewValue());
		LOGGER.info("-----------------------------------------------");

	}
}

 

Next configure this ‘MyCacheEnventListener’ in ehcache.xml file.

 

ehcache.xml

 

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

	<cache alias="myEmployeeCache">
		<key-type>java.lang.Object</key-type>
		<value-type>java.lang.Object</value-type>
		<expiry>
			<ttl unit="seconds">10</ttl>
		</expiry>

		<listeners>
			<listener>
				<class>com.sample.app.listeners.MyCacheEnventListener</class>
				<event-firing-mode>SYNCHRONOUS</event-firing-mode>
				<event-ordering-mode>UNORDERED</event-ordering-mode>
				<events-to-fire-on>CREATED</events-to-fire-on>
				<events-to-fire-on>EXPIRED</events-to-fire-on>
			</listener>
		</listeners>

		<resources>
			<heap unit="entries">2</heap>
			<offheap unit="MB">10</offheap>
		</resources>


	</cache>


</config>

 

As you observe the definition of xml file, I set event-firing-mode to SYNCHRONOUS for the demo purpose, you can set this to 'ASYNCHRONOUS' in production.

 

Specify ehcache.xml file location in application.yml file.

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

 

Follow below step-by-step procedure to build complete working application.

 

Step 1: Create new maven project ‘spring-cache-event-listener’.

 

Step 2: Update pom.xml with maven dependencies.

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.sample.app</groupId>
	<artifactId>spring-cache-event-listener</artifactId>
	<version>1</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.6</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>

		<dependency>
			<groupId>org.ehcache</groupId>
			<artifactId>ehcache</artifactId>
		</dependency>

		<dependency>
			<groupId>javax.cache</groupId>
			<artifactId>cache-api</artifactId>
		</dependency>

	</dependencies>
</project>

Step 3: Create ehcache.xml file under src/main/resources folder.

 

ehcache.xml

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

	<cache alias="myEmployeeCache">
		<key-type>java.lang.Object</key-type>
		<value-type>java.lang.Object</value-type>
		<expiry>
			<ttl unit="seconds">10</ttl>
		</expiry>

		<listeners>
			<listener>
				<class>com.sample.app.listeners.MyCacheEnventListener</class>
				<event-firing-mode>SYNCHRONOUS</event-firing-mode>
				<event-ordering-mode>ORDERED</event-ordering-mode>
				<events-to-fire-on>EVICTED</events-to-fire-on>
				<events-to-fire-on>EXPIRED</events-to-fire-on>
				<events-to-fire-on>REMOVED</events-to-fire-on>
				<events-to-fire-on>CREATED</events-to-fire-on>
				<events-to-fire-on>UPDATED</events-to-fire-on>

			</listener>
		</listeners>

		<resources>
			<heap unit="entries">2</heap>
			<offheap unit="MB">10</offheap>
		</resources>


	</cache>


</config>

Step 4: Create application.yml file under src/main/resources folder.

 

application.yml

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

Step 5: Create Employee model class.

 

Employee.java

package com.sample.app.model;

import java.io.Serializable;

public class Employee implements Serializable{
	private int id;
	private String firstName;
	private String lastName;

	public Employee(int id, String firstName, String lastName) {
		this.id = id;
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
	}

}

Step 6: Define EmployeeService class.

 

EmployeeService.java

package com.sample.app.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.sample.app.model.Employee;

@Service
@CacheConfig(cacheNames = "myEmployeeCache")
public class EmployeeService {

	private static List<Employee> emps = new ArrayList<>();

	static {
		emps.add(new Employee(1, "Ram", "Kota"));
		emps.add(new Employee(2, "Raj", "Majety"));
		emps.add(new Employee(3, "PTR", "Navakotla"));
		emps.add(new Employee(4, "Krishna", "Boppana"));
	}

	@Cacheable(key = "{#id}")
	public Employee getEmployeeById(int id) {
		System.out.println("getEmployeeById: Getting the informaiton from internal list");
		
		for (Employee emp : emps) {
			if (id == emp.getId()) {
				return emp;
			}
		}
		return null;
	}

	@Cacheable(key = "{#name}")
	public Employee getEmployeeByFirstName(String name) {
		System.out.println("getEmployeeByFirstName: Getting the informaiton from internal list");
		
		for (Employee emp : emps) {
			if (name.equals(emp.getFirstName())) {
				return emp;
			}
		}
		return null;
	}
}

Step 7: Define MyCacheEnventListener class.

MyCacheEnventListener.java

package com.sample.app.listeners;

import org.ehcache.event.CacheEvent;
import org.ehcache.event.CacheEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyCacheEnventListener implements CacheEventListener<Object, Object> {
	private static final Logger LOGGER = LoggerFactory.getLogger(MyCacheEnventListener.class);

	public void onEvent(CacheEvent<? extends Object, ? extends Object> cacheEvent) {
		LOGGER.info("\n-----------------------------------------------");
		LOGGER.info("Event received");
		LOGGER.info("event type: {}", cacheEvent.getType());
		LOGGER.info("event key: {}", cacheEvent.getKey());
		LOGGER.info("old value: {}", cacheEvent.getOldValue());
		LOGGER.info("new value: {}", cacheEvent.getNewValue());
		LOGGER.info("-----------------------------------------------");

	}
}

 

Step 8: Define CacheConfig class.

 

CacheConfig.java

package com.sample.app.config;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {

} 

 

Step 9: Define main application class.

 

App.java

package com.sample.app;

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;

@SpringBootApplication
public class App {

	private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

	@Autowired
	private EmployeeService empService;

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

	public void getEmployeeDetails() {

		System.out.println("\n");
		LOGGER.info("\nGetting employee details with id 1");
		Employee emp = empService.getEmployeeById(1);
		LOGGER.info("emp : {}", emp);

		System.out.println("\n");
		LOGGER.info("Getting employee details with name 'Krishna'");
		emp = empService.getEmployeeByFirstName("Krishna");
		LOGGER.info("emp : {}", emp);
	}

	@Bean
	public CommandLineRunner demo() {
		return (args) -> {

			getEmployeeDetails();

			LOGGER.info("Sleeping for 4 seconds");
			TimeUnit.SECONDS.sleep(4);
			getEmployeeDetails();

			LOGGER.info("Sleeping for 4 seconds");
			TimeUnit.SECONDS.sleep(4);
			getEmployeeDetails();

			LOGGER.info("Sleeping for 4 seconds");
			TimeUnit.SECONDS.sleep(4);
			getEmployeeDetails();

		};
	}
}

 

Total project structure looks like below.

 


 

Run App.java, you will see below messages in console.

Getting employee details with id 1
getEmployeeById: Getting the informaiton from internal list
2022-06-30 16:15:17.063  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : 
-----------------------------------------------
2022-06-30 16:15:17.064  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : Event received
2022-06-30 16:15:17.064  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event type: CREATED
2022-06-30 16:15:17.064  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event key: [1]
2022-06-30 16:15:17.064  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : old value: null
2022-06-30 16:15:17.064  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : new value: Employee [id=1, firstName=Ram, lastName=Kota]
2022-06-30 16:15:17.064  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : -----------------------------------------------
2022-06-30 16:15:17.065  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=1, firstName=Ram, lastName=Kota]


2022-06-30 16:15:17.065  INFO 82133 --- [           main] com.sample.app.App                       : Getting employee details with name 'Krishna'
getEmployeeByFirstName: Getting the informaiton from internal list
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : 
-----------------------------------------------
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : Event received
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event type: CREATED
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event key: [Krishna]
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : old value: null
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : new value: Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:17.066  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : -----------------------------------------------
2022-06-30 16:15:17.066  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:17.067  INFO 82133 --- [           main] com.sample.app.App                       : Sleeping for 4 seconds


2022-06-30 16:15:21.069  INFO 82133 --- [           main] com.sample.app.App                       : 
Getting employee details with id 1
2022-06-30 16:15:21.077  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=1, firstName=Ram, lastName=Kota]


2022-06-30 16:15:21.078  INFO 82133 --- [           main] com.sample.app.App                       : Getting employee details with name 'Krishna'
2022-06-30 16:15:21.078  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:21.078  INFO 82133 --- [           main] com.sample.app.App                       : Sleeping for 4 seconds


2022-06-30 16:15:25.079  INFO 82133 --- [           main] com.sample.app.App                       : 
Getting employee details with id 1
2022-06-30 16:15:25.080  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=1, firstName=Ram, lastName=Kota]


2022-06-30 16:15:25.080  INFO 82133 --- [           main] com.sample.app.App                       : Getting employee details with name 'Krishna'
2022-06-30 16:15:25.080  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:25.080  INFO 82133 --- [           main] com.sample.app.App                       : Sleeping for 4 seconds


2022-06-30 16:15:29.082  INFO 82133 --- [           main] com.sample.app.App                       : 
Getting employee details with id 1
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : 
-----------------------------------------------
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : Event received
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event type: EXPIRED
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event key: [1]
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : old value: Employee [id=1, firstName=Ram, lastName=Kota]
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : new value: null
2022-06-30 16:15:29.085  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : -----------------------------------------------
getEmployeeById: Getting the informaiton from internal list
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : 
-----------------------------------------------
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : Event received
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event type: CREATED
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event key: [1]
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : old value: null
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : new value: Employee [id=1, firstName=Ram, lastName=Kota]
2022-06-30 16:15:29.087  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : -----------------------------------------------
2022-06-30 16:15:29.087  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=1, firstName=Ram, lastName=Kota]


2022-06-30 16:15:29.087  INFO 82133 --- [           main] com.sample.app.App                       : Getting employee details with name 'Krishna'
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : 
-----------------------------------------------
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : Event received
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event type: EXPIRED
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event key: [Krishna]
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : old value: Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : new value: null
2022-06-30 16:15:29.088  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : -----------------------------------------------
getEmployeeByFirstName: Getting the informaiton from internal list
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : 
-----------------------------------------------
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : Event received
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event type: CREATED
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : event key: [Krishna]
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : old value: null
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : new value: Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:29.089  INFO 82133 --- [e [_default_]-0] c.s.app.listeners.MyCacheEnventListener  : -----------------------------------------------
2022-06-30 16:15:29.089  INFO 82133 --- [           main] com.sample.app.App                       : emp : Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-30 16:15:59.100  INFO 82133 --- [ionShutdownHook] org.ehcache.core.EhcacheManager          : Cache 'myEmployeeCache' removed from EhcacheManager.

 

You can download complete working application from this link.


 

 

Previous                                                 Next                                                 Home

Wednesday, 29 June 2022

spring boot: ehcache hello world example

Ehcache is a high-performance caching library for Java. In this post, I am going to explain how to integrate Ehcache with spring boot application.

 

Step 1: Enable caching in your spring boot application.

 

Step 2: Create ehcache.xml configuration and define the caches there.

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

	<cache alias="myEmployeeCache">
		<key-type>java.lang.Object</key-type>
		<value-type>java.lang.Object</value-type>
		<expiry>
			<ttl unit="seconds">10</ttl>
		</expiry>

		<resources>
			<heap unit="entries">2</heap>
			<offheap unit="MB">10</offheap>
		</resources>
	</cache>


</config>

 

Above snippet defines a cache ‘myEmployeeCache’ where key and object are of type Object. An entry can live 10 seconds in the cache.

 

Step 3: Specify cache configuration to spring by adding below property.

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

Find the below working application.

 

Step 1: Create new maven project ‘spring-ehcache-demo’.

 

Step 2: Update pom.xml with maven dependencies.

 

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.sample.app</groupId>
	<artifactId>spring-ehcache-demo</artifactId>
	<version>1</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.6</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>

		<dependency>
			<groupId>org.ehcache</groupId>
			<artifactId>ehcache</artifactId>
		</dependency>

		<dependency>
			<groupId>javax.cache</groupId>
			<artifactId>cache-api</artifactId>
		</dependency>

	</dependencies>
</project>

 

Step 3: Create application.yml file under src/main/resources folder.

 

application.yml

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

 

Step 4: Create ehcache.xml file under src/main/resources folder.

 

ehcache.xml

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

	<cache alias="myEmployeeCache">
		<key-type>java.lang.Object</key-type>
		<value-type>java.lang.Object</value-type>
		<expiry>
			<ttl unit="seconds">10</ttl>
		</expiry>

		<resources>
			<heap unit="entries">2</heap>
			<offheap unit="MB">10</offheap>
		</resources>
	</cache>


</config>

Step 5: Define Employee model class.

 

Employee.java

package com.sample.app.model;

import java.io.Serializable;

public class Employee implements Serializable{
	private int id;
	private String firstName;
	private String lastName;

	public Employee(int id, String firstName, String lastName) {
		this.id = id;
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
	}

}

Step 6: Define EmployeeService class.

 

EmployeeService.java

package com.sample.app.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.sample.app.model.Employee;

@Service
@CacheConfig(cacheNames = "myEmployeeCache")
public class EmployeeService {

	private static List<Employee> emps = new ArrayList<>();

	static {
		emps.add(new Employee(1, "Ram", "Kota"));
		emps.add(new Employee(2, "Raj", "Majety"));
		emps.add(new Employee(3, "PTR", "Navakotla"));
		emps.add(new Employee(4, "Krishna", "Boppana"));
	}

	@Cacheable(key = "{#id}")
	public Employee getEmployeeById(int id) {
		System.out.println("getEmployeeById: Getting the informaiton from internal list");
		
		for (Employee emp : emps) {
			if (id == emp.getId()) {
				return emp;
			}
		}
		return null;
	}

	@Cacheable(key = "{#name}")
	public Employee getEmployeeByFirstName(String name) {
		System.out.println("getEmployeeByFirstName: Getting the informaiton from internal list");
		
		for (Employee emp : emps) {
			if (name.equals(emp.getFirstName())) {
				return emp;
			}
		}
		return null;
	}
}

Step 7: Define CacheConfig class.

 

CacheConfig.java

package com.sample.app.config;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableCaching
public class CacheConfig {

}

Step 8: Define main application class.

 

App.java

package com.sample.app;

import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;

@SpringBootApplication
public class App {

	@Autowired
	private EmployeeService empService;

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

	public void getEmployeeDetails() {

		Employee emp = empService.getEmployeeById(1);
		System.out.println(emp);

		emp = empService.getEmployeeByFirstName("Krishna");
		System.out.println(emp);
	}

	@Bean
	public CommandLineRunner demo() {
		return (args) -> {

			getEmployeeDetails();

			System.out.println("\nSleeping for 4 seconds");
			TimeUnit.SECONDS.sleep(4);
			getEmployeeDetails();

			System.out.println("\n\nSleeping for 4 seconds");
			TimeUnit.SECONDS.sleep(4);
			getEmployeeDetails();

			System.out.println("\n\nSleeping for 4 seconds");
			TimeUnit.SECONDS.sleep(4);
			getEmployeeDetails();

		};
	}
}

Total project structure looks like below.



Run App.java, you will see below messages in console.

getEmployeeById: Getting the informaiton from internal list
Employee [id=1, firstName=Ram, lastName=Kota]
getEmployeeByFirstName: Getting the informaiton from internal list
Employee [id=4, firstName=Krishna, lastName=Boppana]

Sleeping for 4 seconds
Employee [id=1, firstName=Ram, lastName=Kota]
Employee [id=4, firstName=Krishna, lastName=Boppana]


Sleeping for 4 seconds
Employee [id=1, firstName=Ram, lastName=Kota]
Employee [id=4, firstName=Krishna, lastName=Boppana]


Sleeping for 4 seconds
getEmployeeById: Getting the informaiton from internal list
Employee [id=1, firstName=Ram, lastName=Kota]
getEmployeeByFirstName: Getting the informaiton from internal list
Employee [id=4, firstName=Krishna, lastName=Boppana]
2022-06-29 21:33:13.603  INFO 4091 --- [ionShutdownHook] org.ehcache.core.EhcacheManager          : Cache 'myEmployeeCache' removed from EhcacheManager.

From the output, you can confirm that employee details are served from internal collection for the first time and, till next 10 seconds data is served from the ehcache.

 

You can download complete working application from this link.


Previous                                                 Next                                                 Home