Spring – Application events

Learn to use create publisher-subscriber based events in Spring applications. Spring has inbuilt support for creating application events, publish them and then listen to it in event handlers. There are a few simple guidelines to follow to create / listen application events:

  1. the event should extend ApplicationEvent
  2. the publisher should inject an ApplicationEventPublisher object
  3. the listener should implement the ApplicationListener interface

1. Why Spring Events

Sometimes in your spring application, you may want to add capability for listening specific application events so that you can process these events as per application logic.

Examples of these events can be when a employee is added/ deleted; or a certain kind of transaction completed or rolled back. You can always write the event processing code as another method within existing application code, BUT then it will be tightly coupled with your existing code and you will not have much handle to change it later (suppose you don’t want to process those events for certain duration).

If you can configure event processors through your application context file, then you need not to change your application code as well as event processor code in most circumstances. Any time you need to switch off event processing; OR want to add another event processor for that event the all you need to do it change your context file configuration and that’s it. Sounds good !!

In spring event-based communication model, the sender component just publishes an event without knowing who the receiver will be. Actually, there may be more than one receiver component. Also, the receiver needn’t know who is publishing the event. Listener can listen to multiple events from different senders at the same time. In this way, the sender and receiver components are loosely coupled.

Let’s learn how we can achieve this publish and listen events in your spring application.

2. Publish and Listen Spring Application Events

2.1. Create Custom Application Event Class

All event classes must extend the ApplicationEvent class.

public class EmployeeEvent extends ApplicationEvent
	private static final long serialVersionUID = 1L;
	private String eventType;
	private EmployeeDTO employee;
	//Constructor's first parameter must be source
	public EmployeeEvent(Object source, String eventType, EmployeeDTO employee) 
		//Calling this super class constructor is necessary
		this.eventType = eventType;
		this.employee = employee;

	public String getEventType() {
		return eventType;

	public EmployeeDTO getEmployee() {
		return employee;

2.2. Publisher – Implement ApplicationEventPublisherAware Interface

Any bean, which implements ApplicationEventPublisherAware interface, can use its publishEvent() method to send event to listeners.

@Service ("employeeManager")
public class EmployeeManagerImpl implements EmployeeManager, ApplicationEventPublisherAware
	private EmployeeDAO dao;
	private ApplicationEventPublisher publisher;
	//You must override this method; It will give you acces to ApplicationEventPublisher
	public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
		this.publisher = publisher;
	public EmployeeDTO createNewEmployee()
		EmployeeDTO employee =  dao.createNewEmployee();
		//publishing the veent here
		publisher.publishEvent(new EmployeeEvent(this, "ADD", employee));
		return employee;

2.3. Subscriber/Listener – Implement ApplicationListener Interface

For a bean to listen to certain events, it must implement the ApplicationListener interface and handle the events in the onApplicationEvent() method. Actually, Spring will notify a listener of all events, so you must filter the events by yourself.

If you use generics, Spring will deliver only messages that match the generic type parameter. In this example, I am using generics code to listen only EmployeeEvent.

public class UserEventsProcessor implements ApplicationListener<EmployeeEvent> 
	public void onApplicationEvent(EmployeeEvent event) 
		EmployeeEvent employeeEvent = (EmployeeEvent) event;

		System.out.println("Employee " + employeeEvent.getEventType() 
                          + " with details : " + employeeEvent.getEmployee());

		// Do more processing as per application logic

2.4. Configure the beans in application context file

<context:component-scan base-package="com.howtodoinjava.demo" />

<bean class="com.howtodoinjava.demo.processors.UserEventsProcessor" />

2.5. Demo

public class TestSpringContext 
	public static void main(String[] args) throws Exception 
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

		EmployeeController controller = context.getBean(EmployeeController.class);

Observe the output.

INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
Employee ADD with details : Employee [id=1, firstName=Lokesh, lastName=Gupta, type=null]

Great. We are able to listen the events now and we can process then the way we want.

Please note that application context itself also publish container events such as ContextClosedEvent, ContextRefreshedEvent, and RequestHandledEvent. If any of your beans want to be notified of these events, they can implement the ApplicationListener interface.

3. Other class files used in this example

Here EmployeeDTO class looks like this:

public class EmployeeDTO 
	private Integer id;
	private String firstName;
	private String lastName;
	private String designation;

	public EmployeeDTO(String designation) 
		this.id = -1;
		this.firstName = "dummy";
		this.lastName = "dummy";
		this.designation = designation;

	public EmployeeDTO() {
		// TODO Auto-generated constructor stub

	//Setters and Getters

	public String toString() {
		return "Employee [id=" + id + ", firstName=" + firstName
				+ ", lastName=" + lastName + ", type=" + designation + "]";
public interface EmployeeDAO 
	public EmployeeDTO createNewEmployee();
@Repository ("employeeDao")
public class EmployeeDAOImpl implements EmployeeDAO
	public EmployeeDTO createNewEmployee()
		EmployeeDTO e = new EmployeeDTO();
		return e;
	public void initBean() {
		System.out.println("Init Bean for : EmployeeDAOImpl");
	public void destroyBean() {
		System.out.println("Init Bean for : EmployeeDAOImpl");
public interface EmployeeManager 
	public EmployeeDTO createNewEmployee();

Happy Learning !!

Leave a Reply

Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.