Do you know about @EventListener and ApplicationEventPublisher in Spring?
Hello readers,
Spring application event publisher and event listener allows us to publish and listen to an event within application context. Kindly note that this feature cannot be used to publish and listen to an event beyond application context boundaries, we should use MQ or Apache Kafka to mitigate such scenarios.
It is very useful when separating independent logic into different methods and easy to extend if in case needs to amend additional business logic without touching existing code.
Let's take an example of creating employee in the system and triggering an email once employee has been created. As soon as employee is created, we can separate out email trigger logic.
There are some syntactical differences present in Spring version before 4.2 and after 4.2. It is very easy to implement.
If you are using Spring 4.2, it is necessary to extend event object with ApplicationEvent object
public class EmployeeEvent extends ApplicationEvent{
public String name;
public String department;
}
Also, to use publishEvent method of ApplicationEventPublisherAware interface it is necessary to implement ApplicationEventPublisherAware interface in your service class which publishes an event.
@service
public class EmployeeService implementes ApplicationEventPublisherAware{
@Autowired
private ApplicationEventPublisher publisher;
public void createEmployee(){
publisher.publishEvent(new EmployeeEvent("name","department"));
}
}
Inside the component where its listening to an event object should implement ApplicationListener interface
@Component
public class EmployeeEventListener implements ApplicationListener<EmployeeEvent>{
public void onApplicationEvent(EmployeeEvent event){
// processing around received event object
}
}
Post Spring 4.2, above restrictions have been removed.
Any entity can be considered as application event object. Also, we can simply annotate any method with @EventListener annotation to represent it as listener method.
@Component
public class EmployeeService{
@Autowired
private ApplicationEventPublisher eventPublisher;
public void create(Employee employee){
log.info("Employee has been created successfully {}", employee.getName());
eventPublisher.publishEvent(employee);
}
@EventListener(Employee.class)
public void sendEmail(Employee employee){
log.info("Sending email post employee creation.. {}", employee.getName());
}
}
Under few cases we would need to run logic in asynchronous manner, like sending an email can be done in asynchrounous manner. This can be achieved by applying @Async annotation on listener method.
Please note we should also add @EnableAsync annotation on launcher class to let spring usage of async feature.
@SpringBootApplication
@EnableAsync
public class SpringEventsApplication {....}
@EventListener(Employee.class)
@Async
public void sendEmail(Employee employee){
Conclusion:
This is one of the important and useful feature of spring boot. We can also use this feature to listen to an application context events like context load or destroy. This feature allows us to extend listener facility without touching existing code untouched.