Lab M02P01
Using events, you can decouple application components. Spring framework's core functionality supports events by implementation of the Observer pattern. Spring itself fires several types of events as Context events. You can implement your own eventing model and use Spring's API to fire events and to listen for events.
-
Let's implement application event which notify other components of your application about newly created Book entity. Events typically inform about something already happened. First, create the BookCreatedEvent class in the ite.librarymaster.event package. Event structure can look like:
Event is just the data holder, so we can use event properties public access, or we can use Java record.public class BookCreatedEvent { public Long id; public String catId; public String title; public String publisher; public String author; public String isbn; public BookGenre genre; } -
Now, implement an event publisher. Define interface with the fireEvent() method and then implementation. The best is to introduce generic event support in your application. Create the GenericEvent class, which holds generic event payload.
Then define publisher interface.public class GenericEvent <T> { private T payload; public GenericEvent(T payload) { this.payload = payload; } public T getPayload() { return payload; } }And publisher implementation. Spring framework provides the ApplicationEventPublisher bean, you can use to publish events.public interface DomainEventPublisher { void fireEvent(GenericEvent payload); }@Component public class SpringDomainEventPublisher implements DomainEventPublisher { @Autowired ApplicationEventPublisher applicationEventPublisher; @Override public void fireEvent(GenericEvent payload) { applicationEventPublisher.publishEvent(payload); } } -
Now, use the DomainEventPublisher in the LibraryAdminServiceImpl to fire the BookCreatedEvent when new Book entity is created. We can say the LibraryAdminService is the domain service, so it can produce domain events like the BookCreatedEvent.
-
What is still missing, is an event listener. You can create one in the service package for instance. Listener will just log received event. Implement Spring bean LoggerAuditService with method annotated with the EventListener annotation.
@EventListener public void log(GenericEvent event) { LOG.info("AUDIT LOG: {}", event.getPayload()); }Now, run LibraryAdminServiceImplTest integration test and check logs for event messages.
It would be great, if the BookCreatedEvent is fired only if current Transaction is successfully COMMITTED. Spring supports binding events to Tx. Just replace the @EventListener annotation with the @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) one. Event processing is executed in a caller's Thread by default, but you can add @Async annotation at Listener's method to execute event processing asynchronously. You need to add @EnableAsync annotation to SpringBoot configuration. (just check the Application class)
-
The example of the Spring context event listener is in the ContextEventListener class. If you need to execute custom logic upon Spring context initialization phases, the Spring Context based events is the right ones to use.
Application events
The event publishing is provided by ApplicationContext. Spring’s eventing mechanism is designed for simple communication between Spring beans within the same application context. It is implementation of the Observer pattern. Spring handles either custom event classes which extends the ApplicationEvent, or any arbitrary classes.
Build-in events
Spring framework is able to publish build-in events as:
- ContextRefreshedEvent
- ContextStartedEvent
- ContextStoppedEvent
- ContextClosedEvent
- RequestHandledEvent
- ServletRequestHandledEvent
Tx bound events
The @TransactionalEventListener annotation, which is an extension of @EventListener, that allows binding the listener of an event to a phase of the transaction.
- TransactionPhase.AFTER_COMMIT
- TransactionPhase.AFTER_ROLLBACK
- TransactionPhase.AFTER_COMPLETION
- TransactionPhase.BEFORE_COMMIT