I. Introductory cases
1. Adding dependencies
First, add the Spring Boot and Spring Event dependencies to the file:
<dependencies> <dependency> <groupId></groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
2. Defining custom events
Create a custom event class, CustomEvent, inheriting from ApplicationEvent:
package ; import ; public class CustomEvent extends ApplicationEvent { private String message; public CustomEvent(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } }
3. Creating event listeners
Create an event listener class CustomEventListener that implements the ApplicationListener interface:
package ; import ; import ; import ; @Component public class CustomEventListener implements ApplicationListener<CustomEvent> { @Override public void onApplicationEvent(CustomEvent event) { ("Received custom event - " + ()); } }
4. Publication of events
In the DemoApplication class, inject the ApplicationEventPublisher and publish the custom event:
package ; import ; import ; import ; import ; import ; import ; @SpringBootApplication public class DemoApplication implements CommandLineRunner { @Autowired private ApplicationEventPublisher publisher; public static void main(String[] args) { (DemoApplication.class, args); } @Override public void run(String... args) throws Exception { CustomEvent event = new CustomEvent(this, "Hello, Spring Event!"); (event); } }
5. Running the application
Run the DemoApplication class to start the Spring Boot application. You should see the following output on the console:
received:$$SpringCGLIB$$0@6e3ecf5cmessages;timing:1731466981066;messages:Hello, Spring Event!
Second, Spring-Event execution principle
The Spring Event mechanism is an event-driven model in the Spring Framework for decoupling and communicating between different components of an application. The following is a detailed explanation of how Spring Event works:
1. Event
Definition: An event is a specific action or state change that occurs in an application.
Implementation: In Spring, events are usually represented by a class that inherits from ApplicationEvent. For example, the CustomEvent we defined earlier is a custom event.
2. Event Publisher
Definition : An event publisher is a component responsible for creating and publishing events.
Implementation: In Spring, events can be published through the ApplicationEventPublisher interface. Typically, this interface is injected via dependency injection into the class that needs to publish the event.
3. Event Listener
Definition : An event listener is a component responsible for handling events.
Implementation: In Spring, event listeners can be defined by implementing the ApplicationListener interface or using the @EventListener annotation.
4. Process of dissemination of events
1. Event creation:
The event publisher creates an instance of ApplicationEvent and passes the necessary parameters.
2. Event release:
The event publisher calls the publishEvent method of the ApplicationEventPublisher to pass the event object to the Spring container.
3. Event distribution:
When the Spring container receives an event, it looks for all listeners registered for that event type.
The Spring container calls the onApplicationEvent method of each listener (if using the ApplicationListener interface) or the method with the @EventListener annotation.
4. Incident handling:
The listener receives the event and executes the appropriate business logic based on the content of the event.
5. Asynchronous event processing
Default behavior: Spring events are processed synchronously by default, i.e., the event publisher waits for all listeners to finish processing the event before continuing to execute subsequent code.
Asynchronous Processing: Asynchronous event processing can be implemented by configuring ApplicationEventMulticaster. Typically, asynchronous processing can be implemented by configuring TaskExecutor in or .
6. Explanation of sample code
CustomEvent: defines a custom event class that inherits from ApplicationEvent and adds a message property.
CustomEventListener: defines an event listener class that implements the ApplicationListener<CustomEvent> interface and overrides the onApplicationEvent method to handle events.
DemoApplication: main class, implements the CommandLineRunner interface, creates and publishes a CustomEvent event in the run method.
summarize
The Spring Event mechanism enables a loosely coupled and flexible event-driven architecture between components through event publishers, event listeners, and events themselves. In this way, it is easier to manage and extend the functionality of an application.
Third, in-depth exploration of the specific execution process and mechanism behind (event).
1. event publish method publishEvent
When you call the publishEvent method of the ApplicationEventPublisher, the Spring container performs a series of actions to handle the event. Here are the detailed steps:
When you call the publishEvent method of the ApplicationEventPublisher, the Spring container performs a series of actions to handle the event. Here are the detailed steps:
1.1 Calling the publishEvent method
(event);
1.2 AbstractApplicationContext hit the nail on the head publishEvent methodologies
The implementation class of the ApplicationEventPublisher interface is usually AbstractApplicationContext, which is one of the core classes of the Spring container.
The publishEvent method in AbstractApplicationContext calls the doPublishEvent method to handle the event.
public void publishEvent(ApplicationEvent event) { assertContextActive(); getApplicationEventMulticaster().multicastEvent(event); }
2. ApplicationEventMulticaster
ApplicationEventMulticaster is the component responsible for broadcasting events to all registered listeners. By default, Spring uses the SimpleApplicationEventMulticaster implementation.
2.1 multicastEvent method
The multicastEvent method of SimpleApplicationEventMulticaster iterates through all registered listeners and calls their onApplicationEvent methods.
@Override public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); Executor executor = getTaskExecutor(); for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { if (executor != null) { (() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } }
3. Event listener invocation
3.1 invokeListener method
The invokeListener method calls the specific listener method to handle the event.
private void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) { ErrorHandler errorHandler = getErrorHandler(); if (errorHandler == null) { doInvokeListener(listener, event); } else { try { doInvokeListener(listener, event); } catch (Throwable err) { (err); } } } private void doInvokeListener(ApplicationListener<?> listener, ApplicationEvent event) { try { // Calls the onApplicationEvent method of the listener. (event); } catch (ClassCastException ex) { String msg = (); if (msg == null || matchesClassName(ex, (), msg) || matchesClassName(ex, (event).getRawClass(), msg)) { String className = ().getName(); if (()) { ("Non-matching event type for listener [" + className + "]"); } } else { throw ex; } } }
4. Asynchronous event processing
4.1 Configuring TaskExecutor
If you want event processing to be asynchronous, you can configure TaskExecutor in or . For example:
spring: task: execution: pool: core-size: 5 max-size: 10 queue-capacity: 100
4.2 Customizing ApplicationEventMulticaster
More complex event handling logic can also be implemented by customizing ApplicationEventMulticaster. For example:
@Configuration public class EventConfig { @Bean public ApplicationEventMulticaster applicationEventMulticaster() { SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(); (new SimpleAsyncTaskExecutor()); return eventMulticaster; } }
5. Event listener registration
5.1 Passing the @Component annotation
You can register a listener class as a Spring-managed bean using the @Component annotation.
@Component public class CustomEventListener implements ApplicationListener<CustomEvent> { @Override public void onApplicationEvent(CustomEvent event) { ("Received custom event - " + ()); } }
5.2 Passing the @EventListener annotation
You can also define event listener methods using the @EventListener annotation.
@Component public class CustomEventListener { @EventListener public void handleCustomEvent(CustomEvent event) { ("Received custom event - " + ()); } }
summarize
With the above steps, we can see the detailed execution flow behind (event). the Spring container broadcasts the event to all registered listeners via ApplicationEventMulticaster and calls their onApplicationEvent method to handle the event. In addition, Spring provides asynchronous event handling and the ability to customize event multicasters to meet more complex application requirements.