在之前的博客中有介绍过发布订阅模式, 也就是观察者模式, 想要了解的同学可以看我博客https://editor.csdn.net/md/?articleId=126689739
他的uml图如下(图一)

这里我们在重点讲一下发布订阅模式在spring源码中的应用
为了大家有一个整体的认识, 我先把主要涉及到的类先画出uml, 如下

接下来我们来分析一下源码
ApplicationListener作为观察者, 定义onApplicationEvent。 对应图一的Observer
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
事件的发布, 是通过ApplicationContext 的publishEvent , 他的默认实现是接口ApplicationEventPublisher, 所以 ApplicationContext 就作为观察目标(图一的Subject)
public interface ApplicationEventPublisher {
/**
* Notify all matching listeners registered with this
* application of an application event. Events may be framework events
* (such as RequestHandledEvent) or application-specific events.
* @param event the event to publish
* @see org.springframework.web.context.support.RequestHandledEvent
*/
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
/**
* Notify all matching listeners registered with this
* application of an event.
* If the specified {@code event} is not an {@link ApplicationEvent},
* it is wrapped in a {@link PayloadApplicationEvent}.
* @param event the event to publish
* @since 4.2
* @see PayloadApplicationEvent
*/
void publishEvent(Object event);
}
我们再看一下实现细节, 可以找到AbstractApplicationContext, 代码片段如下
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
重点看 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);这是他的具体实现, 可以定位到org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent, 代码如下, 也是用for循环去便利观察者, 参考图一中的for
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
最后我们看一下invokeListener的实现, doInvokeListener, 可以发现, 是调用了观察者ApplicationListener的onApplicationEvent方法
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isDebugEnabled()) {
logger.debug("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
到这里你是不是已近明白了尼