Publish-Subscribe pattern with @EventListener
It would be awkward to develop software with the need to re-implement the same software patterns again and again. Luckily, we have Spring Framework, plenty of adorable libraries, and other superb frameworks (Spring is not the only one). As we all know, Spring Framework provides most of the building blocks we could ever need for software development. Of course, for a long time, the framework had its own implementation of the Observer Pattern, and this was widely used for tracking the application's life cycle events. Starting with Spring Framework 4.2, this implementation and concomitant API was extended to be used for the handling of not only application events but also business logic events. In turn, for the event distribution purposes, Spring now provides an @EventListener annotation for event handling and the ApplicationEventPublisher class for event publishing.
Here we need to clarify that the @EventListener and the ApplicationEventPublisher implement the Publish-Subscribe pattern, which may be seen as a variation of the Observer pattern.
In contrast to the Observer pattern, in the Publish-Subscribe pattern publishers and subscribers don't need to know each other, as is depicted in the following diagram:
A Publish-Subscribe pattern provides an additional level of indirection between the publishers and subscribers. The subscribers are aware of the event channels that broadcast notifications, but usually do not care about publishers' identities. Also, each event channel may have a few publishers at the same time. The preceding diagram should help to spot the difference between Observer and Publish-Subscribe patterns. The Event Channel (also known as a message broker or event bus) may additionally filter incoming messages and distribute them between subscribers. The filtering and routing may happen based on the message content, message topic, or sometimes even both. Consequently, subscribers in a topic-based system will receive all messages published to the topics of interest.
The Spring Framework's @EventListener annotation makes it possible to apply both topic-based and content-based routing. Message types could play the role of topics; the condition attribute enables content-based routing event handling based on the Spring Expression Language (SpEL).