{"id":3712,"date":"2025-11-24T10:00:11","date_gmt":"2025-11-24T15:00:11","guid":{"rendered":"https:\/\/www.mymiller.name\/wordpress\/?p=3712"},"modified":"2025-11-24T10:00:11","modified_gmt":"2025-11-24T15:00:11","slug":"spring-into-action-with-spring-events-a-comprehensive-guide","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/spring_events\/spring-into-action-with-spring-events-a-comprehensive-guide\/","title":{"rendered":"Spring into Action with Spring Events: A Comprehensive Guide"},"content":{"rendered":"\n<div class=\"wp-block-jetpack-markdown\"><p>Spring Framework offers a robust event handling mechanism that allows different parts of your application to communicate asynchronously. This is crucial for building loosely coupled and responsive applications, especially in a microservices architecture. This blog post will delve into Spring events, covering creation, publishing, and handling, both within a single application and across microservices using Spring Cloud Bus.<\/p>\n<h3>Understanding Spring Events<\/h3>\n<p>At its core, Spring\u2019s event mechanism revolves around three key components:<\/p>\n<ul>\n<li><strong>Event:<\/strong> Any object that extends <code>ApplicationEvent<\/code> acts as an event. This object carries information about the occurred event.<\/li>\n<li><strong>Publisher:<\/strong>  Any object can publish an event by using the <code>ApplicationEventPublisher<\/code> injected by Spring.<\/li>\n<li><strong>Listener:<\/strong>  Any bean implementing <code>ApplicationListener<\/code> can listen for and respond to specific events.<\/li>\n<\/ul>\n<h3>Creating a Custom Event<\/h3>\n<p>Let\u2019s start by defining a custom event. Imagine we have an e-commerce application, and we want to generate an event when a new order is placed:<\/p>\n<pre><code>public class OrderCreatedEvent extends ApplicationEvent {\n    private Order order;\n\n    public OrderCreatedEvent(Object source, Order order) {\n        super(source);\n        this.order = order;\n    }\n\n    public Order getOrder() {\n        return order;\n    }\n}\n<\/code><\/pre>\n<p>This <code>OrderCreatedEvent<\/code> carries information about the newly created <code>Order<\/code>.<\/p>\n<h3>Publishing an Event<\/h3>\n<p>Next, we need to publish this event whenever a new order is placed.  We can inject <code>ApplicationEventPublisher<\/code> into our <code>OrderService<\/code> and use it to publish the event:<\/p>\n<pre><code class=\"language-java\">@Service\npublic class OrderService {\n\n    @Autowired\n    private ApplicationEventPublisher publisher;\n\n    public void createOrder(Order order) {\n        \/\/ Logic to save the order\n        publisher.publishEvent(new OrderCreatedEvent(this, order));\n    }\n}\n<\/code><\/pre>\n<h3>Handling an Event<\/h3>\n<p>Now, let\u2019s create a listener to react to <code>OrderCreatedEvent<\/code>. For instance, we might want to send a confirmation email:<\/p>\n<pre><code class=\"language-java\">@Component\npublic class OrderCreatedEventListener implements ApplicationListener&lt;OrderCreatedEvent&gt; {\n\n    @Override\n    public void onApplicationEvent(OrderCreatedEvent event) {\n        Order order = event.getOrder();\n        \/\/ Logic to send confirmation email\n        System.out.println(&quot;Order created: &quot; + order.getId());\n    }\n}\n<\/code><\/pre>\n<p>This listener will be automatically invoked whenever an <code>OrderCreatedEvent<\/code> is published.<\/p>\n<h3>Spring Events in a Single Application<\/h3>\n<p>In a monolithic application, this setup is sufficient for basic event-driven communication. Events are published and consumed within the same application context.<\/p>\n<h3>Spring Cloud Bus for Microservices<\/h3>\n<p>In a microservices environment, things get more complex. Events might need to be propagated across different services. This is where Spring Cloud Bus comes in. It uses a lightweight message broker (like RabbitMQ or Kafka) to distribute events across your microservices.<\/p>\n<p>To use Spring Cloud Bus, you\u2019ll need to:<\/p>\n<ol>\n<li><strong>Include the necessary dependencies<\/strong>: Add <code>spring-cloud-starter-bus-amqp<\/code> (for RabbitMQ) or <code>spring-cloud-starter-bus-kafka<\/code> to your projects.<\/li>\n<li><strong>Configure the message broker<\/strong>: Configure connection details for RabbitMQ or Kafka.<\/li>\n<\/ol>\n<p>Now, when you publish an event in one service, Spring Cloud Bus will distribute it to all other services that are listening for that event type.<\/p>\n<h3>Example:  User Registration Event with Spring Cloud Bus<\/h3>\n<p>Imagine a \u201cuser service\u201d that publishes a <code>UserRegisteredEvent<\/code>. A separate \u201cnotification service\u201d needs to listen for this event to send a welcome email.<\/p>\n<p><strong>User service:<\/strong><\/p>\n<pre><code class=\"language-java\">@Service\npublic class UserService {\n    @Autowired\n    private ApplicationEventPublisher publisher;\n\n    public void registerUser(User user) {\n        \/\/ Logic to save the user\n        publisher.publishEvent(new UserRegisteredEvent(this, user));\n    }\n}\n<\/code><\/pre>\n<p><strong>Notification service:<\/strong><\/p>\n<pre><code class=\"language-java\">@Component\npublic class UserRegisteredEventListener implements ApplicationListener&lt;UserRegisteredEvent&gt; {\n\n    @Override\n    public void onApplicationEvent(UserRegisteredEvent event) {\n        User user = event.getUser();\n        \/\/ Logic to send welcome email\n        System.out.println(&quot;Sending welcome email to: &quot; + user.getEmail());\n    }\n}\n<\/code><\/pre>\n<p>With Spring Cloud Bus, the <code>UserRegisteredEvent<\/code> published in the user service will be automatically delivered to the notification service, triggering the welcome email.<\/p>\n<p>This blog post provided a comprehensive overview of Spring events, covering creation, publishing, and handling in both single applications and microservices environments with Spring Cloud Bus. By leveraging this powerful mechanism, you can build loosely coupled, responsive, and maintainable applications. Remember to choose the right approach based on your application\u2019s architecture and needs. Happy event handling!<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":3713,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[436],"tags":[],"series":[],"class_list":["post-3712","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-spring_events"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/mailbox-2462122_1280-jpg.avif","jetpack-related-posts":[{"id":3724,"url":"https:\/\/www.mymiller.name\/wordpress\/spng_security\/spring-cors-configuration-a-comprehensive-guide\/","url_meta":{"origin":3712,"position":0},"title":"Spring CORS Configuration: A Comprehensive Guide","author":"Jeffery Miller","date":"December 18, 2025","format":false,"excerpt":"Cross-Origin Resource Sharing (CORS) is a security mechanism that browsers implement to restrict web pages from making requests to a different domain than the one that served the web page. This article provides a comprehensive guide to CORS configuration in Spring, covering both enabling and disabling CORS, along with the\u2026","rel":"","context":"In &quot;Spring Security&quot;","block_context":{"text":"Spring Security","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spng_security\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8722078_1280-jpg.avif 3x"},"classes":[]},{"id":3660,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_tracing\/crafting-custom-metrics-for-micrometer-tracing-a-comprehensive-guide\/","url_meta":{"origin":3712,"position":1},"title":"Crafting Custom Metrics for Micrometer Tracing: A Comprehensive Guide","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Micrometer, a versatile application metrics facade, seamlessly integrates with Spring Boot Actuator to capture and expose vital insights into your application\u2019s performance. While Micrometer offers a plethora of pre-defined metrics, you often need to track application-specific metrics that aren\u2019t covered out of the box. This blog post will explore creating\u2026","rel":"","context":"In &quot;Spring Tracing &amp; Observability&quot;","block_context":{"text":"Spring Tracing &amp; Observability","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_tracing\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/08\/car-dashboard-2667434_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/08\/car-dashboard-2667434_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/08\/car-dashboard-2667434_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/08\/car-dashboard-2667434_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/08\/car-dashboard-2667434_1280-jpg.avif 3x"},"classes":[]},{"id":3466,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_shell\/exploring-spring-shell-a-comprehensive-guide\/","url_meta":{"origin":3712,"position":2},"title":"Exploring Spring Shell: A Comprehensive Guide","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Shell seamlessly integrates command-line applications with the Spring framework, offering a robust and flexible environment for developers. In this article, we'll expand on setting up a Spring Shell project and explore its features, with a detailed focus on parameters, options, and annotations available for crafting powerful commands in Java.\u2026","rel":"","context":"In &quot;Spring Shell&quot;","block_context":{"text":"Spring Shell","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_shell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/06\/coding-699318_640.jpg?fit=640%2C437&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/06\/coding-699318_640.jpg?fit=640%2C437&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2016\/06\/coding-699318_640.jpg?fit=640%2C437&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3530,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_databases\/spring-jpa-auditing-track-data-changes\/","url_meta":{"origin":3712,"position":3},"title":"Spring JPA Auditing: Track Data Changes","author":"Jeffery Miller","date":"April 20, 2026","format":false,"excerpt":"In the dynamic world of software development, understanding the complete history of your data is crucial. Who made a change? When did it occur? Who viewed the data? Spring JPA Auditing, combined with custom solutions, offers a comprehensive way to answer these questions, acting as a time machine for your\u2026","rel":"","context":"In &quot;Spring Databases&quot;","block_context":{"text":"Spring Databases","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_databases\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/image.png?fit=1200%2C686&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/image.png?fit=1200%2C686&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/image.png?fit=1200%2C686&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/image.png?fit=1200%2C686&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/06\/image.png?fit=1200%2C686&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3871,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_events\/tracking-user-lifecycle-capturing-login-failed-login-and-signup-events-in-spring-authorization-server\/","url_meta":{"origin":3712,"position":4},"title":"Tracking User Lifecycle: Capturing Login, Failed Login, and Signup Events in Spring Authorization Server","author":"Jeffery Miller","date":"November 24, 2025","format":false,"excerpt":"Understanding how users interact with your Spring Authorization Server is crucial for security, auditing, and gaining insights into user behavior. By capturing key lifecycle events like successful logins, failed login attempts, and new user signups, you can build a robust monitoring system. This post will guide you through the process\u2026","rel":"","context":"In &quot;Spring Events&quot;","block_context":{"text":"Spring Events","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_events\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/technology-6701509_1280-1.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/technology-6701509_1280-1.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/technology-6701509_1280-1.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/technology-6701509_1280-1.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/05\/technology-6701509_1280-1.avif 3x"},"classes":[]},{"id":3824,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_rest\/customizing-reads-triggering-events-on-get-requests-with-spring-data-rest\/","url_meta":{"origin":3712,"position":5},"title":"Customizing Reads: Triggering Events on GET Requests with Spring Data REST","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"While Spring Data REST excels at generating CRUD endpoints, the standard life cycle events we\u2019ve discussed primarily revolve around data modification (Create, Update, Delete). You might encounter scenarios where you need to trigger specific actions or logic when an entity is read via a GET request. Out of the box,\u2026","rel":"","context":"In &quot;Spring Rest&quot;","block_context":{"text":"Spring Rest","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_rest\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/05\/ai-generated-8041774_640.jpg?fit=640%2C479&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/05\/ai-generated-8041774_640.jpg?fit=640%2C479&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/05\/ai-generated-8041774_640.jpg?fit=640%2C479&ssl=1&resize=525%2C300 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3712","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=3712"}],"version-history":[{"count":1,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3712\/revisions"}],"predecessor-version":[{"id":3714,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/3712\/revisions\/3714"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/3713"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=3712"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=3712"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=3712"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=3712"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}