The spring event system includes three components: events, event listeners, and event broadcasters.
Event: applicationevent event listener: applicationlistener, which processes the listened events. Event BROADCASTER: applicationeventmulticaster, which broadcasts springpublish events to all listeners. Spring builds the Event System in the abstractapplicationcontext abstract implementation class of the applicationcontext interface. Abstractapplicationcontext has an applicationeventmulticaster variable. applicationeventmulticaster provides the registry of the container listener. Abstractapplicationcontext builds the event infrastructure in the refresh () Container startup method.
try { // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(); // Register bean processors that intercept bean creation. registerBeanPostProcessors(); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate singletons this late to allow them to access the message source. beanFactory.preInstantiateSingletons(); // Last step: publish corresponding event. publishEvent( new ContextRefreshedEvent( this));}
1. Events broadcaster initialization:
private void initApplicationEventMulticaster() throws BeansException { if (containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME )) { this.applicationEventMulticaster = (ApplicationEventMulticaster) getBean( APPLICATION_EVENT_MULTICASTER_BEAN_NAME , ApplicationEventMulticaster.class ); if (logger.isInfoEnabled()) { logger.info("Using ApplicationEventMulticaster [" + this. applicationEventMulticaster + "]" ); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(); if (logger.isInfoEnabled()) { logger.info("Unable to locate ApplicationEventMulticaster with name '"+ APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this .applicationEventMulticaster + "]"); } } }
You can define a Custom Event broadcaster for the container in the configuration file. You only need to implement applicationeventmulticaster. Spring will register it as the container's event broadcaster through the reflection mechanism, if the configured external event broadcaster is not found, spring automatically uses simpleapplicationeventmulticaster as the event broadcaster. 2. register the event listener
private void registerListeners () throws BeansException { // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! Collection listeners = getBeansOfType(ApplicationListener.class,true,false).values(); for (Iterator it = listeners.iterator(); it.hasNext();) { addListener((ApplicationListener) it.next()); }}protected void addListener(ApplicationListener listener) { getApplicationEventMulticaster().addApplicationListener(listener);}
Based on the reflection mechanism, spring uses the getbeansoftype method of listablebeanfactory to find all the implementations of org from beandefinitionregistry. springframework. context. the applicationlistener bean registers them as the event listener of the container. The actual operation is to add them to the listener Registry provided by the event broadcaster. 3. Release events
public void publishEvent(ApplicationEvent event) { Assert. notNull(event, "Event must not be null"); if (logger .isDebugEnabled()) { logger .debug("Publishing event in context [" + getDisplayName() + "]: " + event); } getApplicationEventMulticaster(). multicastEvent(event); if (this .parent != null) { this .parent .publishEvent(event); }}
In the abstrhevent method of abstractapplicationcontext, spring entrusts applicationeventmulticaster to notify all event listeners. 4. simpleapplicationeventmulticaster, the default event broadcaster of spring
public void multicastEvent( final ApplicationEvent event) { for (Iterator it = getApplicationListeners().iterator(); it.hasNext();) { final ApplicationListener listener = (ApplicationListener) it.next(); getTaskExecutor().execute( new Runnable() { public void run() { listener.onApplicationEvent(event); } }); } }
Traverse each registered listener and start to call the onapplicationevent method of each listener. Because the implementation class of taskexecutor of simpleapplicationeventmulticaster is synctaskexecutor, the event listener processes events synchronously. From the code, we can see that the applicationcontext. publishevent () method needs to be synchronized before returning after each listener completes processing. That is to say, the event mechanism provided by spring is synchronized by default. If you want to use the Asynchronous Method, You can implement the applicationeventmulticaster interface and register the bean with the ID applicationeventmulticaster in the spring container.
Example:
public class AsyncApplicationEventMulticaster extends AbstractApplicationEventMulticaster { private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(); public void setTaskExecutor(TaskExecutor taskExecutor) { this.taskExecutor = (taskExecutor != null ? taskExecutor : new SimpleAsyncTaskExecutor()); } protected TaskExecutor getTaskExecutor() { return this.taskExecutor; } @SuppressWarnings("unchecked") public void multicastEvent(final ApplicationEvent event) { for (Iterator<ApplicationListener> it = getApplicationListeners().iterator(); it.hasNext();) { final ApplicationListener listener = it.next(); getTaskExecutor().execute(new Runnable() { public void run() { listener.onApplicationEvent(event); } }); } }}
Spring Configuration:
<bean id="applicationEventMulticaster" class="com.alibaba.chj.event.AsyncApplicationEventMulticaster" />
After an event is published by spring, all registered Event Listeners will receive the event. Therefore, when processing the event, the event listener must first determine whether the event is of interest. The sping Event System adopts the observer mode. Applicationlistener is the observer interface, which defines the onapplicationevent method. This method is used to process applicationevent events.