This article brings you a detailed analysis of the Spring event mechanism source code. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Foreword: Since there were problems using the Spring event mechanism before, I went to understand the source code of this piece. The Spring event mechanism is actually event publishing/subscription (note that subscription in Spring refers to listening).
PS: Spring version is 5.1.5.RELEASE
Source code analysis
Initialization
The key to initialization is the registration of core components
1. Initialization and registration of ApplicationEventPublisher. The key method is the method prepareBeanFactory() of AbstractApplicationContext
2. Initialization and registration of ApplicationEventMulticaster. The key method is the initApplicationEventMulticaster() method of AbstractApplicationContext
3. The initialization and registration of ApplicationListener, the key method is the registerListeners() method of AbstractApplicationContext
I won’t go into details here, those who are interested can track the key methods by themselves
Event publishing/subscription
The key method for event publishing/subscription is publishEvent of AbstractApplicationContext. The source code is as follows:
protected void publishEvent(Object event, ResolvableType eventType) { // 避免空指针 Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } // 处理event对象,将其转换为ApplicationEvent ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<Object>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); } } // 是否延迟多播,即将事件发布到所有监听器中 if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { //此处为事件监听处理器的调用关键 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // 是否将事件发布到父容器中 if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
Through code tracking, it was found that Spring uses the default implementation of ApplicationEventMulticaster, SimpleApplicationEventMulticaster, to trigger event monitoring. The key method It is the multicastEvent() method, and the source code is as follows:
@Override public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) { // 获取事件类型 ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {//依次遍历事件监听器 // 获取线程池 Executor executor = getTaskExecutor(); if (executor != null) {//线程池不为null,则异步调用监听器 executor.execute(new Runnable() { @Override public void run() { invokeListener(listener, event); } }); } else {// 同步调用监听器 invokeListener(listener, event); } } }
This article has ended here. For more other exciting content, you can pay attention to the Java Video Tutorial column of the PHP Chinese website!
The above is the detailed content of Detailed analysis of Spring event mechanism source code. For more information, please follow other related articles on the PHP Chinese website!