Home » Java » Enterprise Java » How to use Events in Spring 3.x

About Soroosh Sarabadani

Soroosh Sarabadani
My name is Soroosh Sarabadani from Iran. I'm working more than 8 year in development and design Enterprise softwares, with master of software engineering grade.

How to use Events in Spring 3.x

There are many concepts and techniques for creating loosely coupled applications, Event is one of them. Events can eliminate many of dependencies in your code. Some times without events, SRP* is very hard to implement. Observable interface in java can help us to implement events (through Observer Pattern).

But wait, the goal of this post is a fast tutorial about Spring Event. Spring has some nice facilities for creating Event Driven Applications. You can raise a specific event in a bean and listen to it in the other bean.

Imagine a simple application with these requirements:

  • There are some orders that can have different status
  • when an order is in DELIVERED or POSTPONED state we need to send an email to the customer

The first (but not the best) solution for requirement satisfaction is sending email in our Order model, But There are some defects:

  • It’s not responsibility of Order to sending email.
  • If you follow Domain Driven principle, Order is a domain object but Email Sender maybe is a service ( different from Domain Service ) so you can’t use it in your model.

The other solution is raising some events in our Order model after changing its status. I’s not concern of Order what will happen after raising this event. In our example we need to listen to a specific kind of events, analyze them and do some business (Sending Email).

 public class Order implements ApplicationEventPublisherAware {
 private final String orderId;
 private final Date createDate;
 private final CustomerInfo customerInfo;
 private ApplicationEventPublisher eventPublisher;
 private Date lastUpdateDate;
 private Status status;
public Order(String orderId, CustomerInfo customerInfo) {
 this.orderId = orderId;
 this.customerInfo = customerInfo;
 status = Status.MODIFIABLE;
 this.createDate = new Date();
 this.lastUpdateDate = this.createDate;
public String getOrderId() {
 return orderId;
public void checkOut() {
 if (status == Status.DELIVERED) {
 throw new IllegalStateException(String.format("Order is already delivered"));
 this.status = Status.CHECKED_OUT;
 this.lastUpdateDate = new Date();
public void deliver() {
 if (this.status != Status.CHECKED_OUT && this.status != Status.POSTPONED) {
 throw new IllegalStateException(String.format("Order status should be CHECKED OUT for delivery to be called. but is : %s", status));
this.status = Status.DELIVERED;
 this.lastUpdateDate = new Date();
 this.eventPublisher.publishEvent(new OnOrderDelivered(this));
public void postponeDelivery() {
 if (status != Status.CHECKED_OUT && status != Status.POSTPONED) {
 throw new IllegalStateException(String.format("Can not postpone delivery in this state: %s", status));
 this.status = Status.POSTPONED;
 this.lastUpdateDate = new Date();
 this.eventPublisher.publishEvent(new OnOrderPostponed(this));
public Status getStatus() {
 return status;
public CustomerInfo getCustomerInfo() {
 return customerInfo;
public Date getLastUpdateDate() {
 return lastUpdateDate;
public Date getCreateDate() {
 return createDate;
 public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
 this.eventPublisher = applicationEventPublisher;
public static enum Status {

As you see Order is a configurable class, if you have not worked with this concept before, don’t be anguished. For this post just you need to know Configurable classes can create everywhere with new keyword but they are managed by spring, so you can inject other beans in them or use most of the spring facilities with them. I promise to post an article about it as soon as possible.

Order class implements  org.springframework.context.ApplicationEventPublisherAware interface. This interface has a setter method with name setApplicationEventPublisher that presents ApplicationEventPublisher for using in your class. As you see in deliver method we used this object to publish an event (this.eventPublisher.publishEvent(new OnOrderDelivered(this))). You can publish every event that extends org.springframework.context.ApplicationEvent. We have raised another event OnOrderPostponed when an order becomes postponed.

public abstract class OnOrderStatusChanged extends ApplicationEvent {
 private final Order order;
public OnOrderStatusChanged(Order source) {
 this.order = source;
 System.out.println(String.format("Order:%s status is changed to %s", source.getOrderId(), source.getStatus()));
public Order getOrder() {
 return order;
public class OnOrderDelivered extends OnOrderStatusChanged {
 public OnOrderDelivered(Order order) {
public class OnOrderPostponed extends OnOrderStatusChanged {
 public OnOrderPostponed(Order order) {

OnOrderStatusChanged is an abstract class what OnOrderDelivered and OnOrderPostponed extends it. until now we could create our events and raise them. now if you create a spring test and call deliver method of an order you will see “Order:X status is changed to DELIVERED” The last step is doing something when these events published. we want to send an email to the customer when these method raised. additionally it’s valuable for customer to posting the product when his order is in delivered state. Listeners are simple Beans that implements generic ApplicationListener interface. Parameter type in this interface is the type of event that you want to listen to it. it is possible to defince parameter type as the parent and listen to all of its childres. for example in our model if we use OnOrderStatusChanged our listener will catch all event from OnOrderDelivered and OnOrderPostponed

It can be suitable for sending email in our scenario. but we don’t use this model and create two different listener for them.

As you see below their code is very simple

 public class OrderDeliveredEmailSender implements ApplicationListener,Ordered {
 public void onApplicationEvent(OnOrderDelivered event) {
 System.out.println(String.format("Message sent for delivered order to:%s ORDER-ID:%s",event.getOrder().getCustomerInfo().getEmail(),event.getOrder().getOrderId()));
 public int getOrder() {
 return 100;
 public class OrderPostponedEmailSender implements ApplicationListener {
 public void onApplicationEvent(OnOrderPostponed event) {
 System.out.println(String.format("Message sent for postponed order to:%s ORDER-ID:%s", event.getOrder().getCustomerInfo().getEmail(), event.getOrder().getOrderId()));

These two beans will fire onApplicationEvent when  correspond event is raised. For posting product to the customer we need to create another Listener for OnOrderDelivered event.

 public class OnOrderDeliveredPost implements ApplicationListener,Ordered {
 public void onApplicationEvent(OnOrderDelivered onOrderDelivered) {
 System.out.println(String.format("Order:%s is posting for customer.",onOrderDelivered.getOrder().getOrderId()));
 public int getOrder() {
 return 1000;

As you see this listener will send product to the customer when its state is DELIVERED. But wait there what is Ordered interface? if you have not use org.springframework.core.Ordered interface, it is valuable to know that with using this interface you can define the order between beans in a collection. in our scenario customer like to receive an email before we post the product to him. for this purpose these two class implement Ordered interface, don’t forget the lowest order has the highest priority.

*Single Responsibility Principle


Reference: How to use Events in Spring 3.x from our JCG partner Soroosh Sarabadani at the Just another Java blog blog.
(0 rating, 0 votes)
You need to be a registered member to rate this.
5 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
Email address:

Leave a Reply

5 Comments on "How to use Events in Spring 3.x"

newest oldest most voted
Notify of
Kristianto Yanuar

Very nice article! Very helpful!


Thank you very much, man, I am going to implement Spring event firing/listening and the information you have here is exactly what I need.


i tried to run the apps after getting the code but unit test failed and when i debugged i am getting null pointer for eventpublisher.


very good pg


My entire search ended here. The level of detail provided in this blog helped me to understand and relate exactly with my scenario. Thanks a ton!