观察者模式
概述
- 观察者模式,又叫发布订阅模式。定义对象间的一对多的依赖关系,当一个对象状态发生改变时,所有依赖它的对象都得到通知并自动更新。
spring
ApplicationContext 的事件机制就是观察者模式的实现
通过实现 ApplicationListener 的onApplicationEvent 方法。可以监听指定事件。注意实现完毕后要注入要spring容器
监听指定事件
public class ApplicationContextListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
System.out.println("输出contextRefreshedEvent 监听事件内容");
}
}
自定义事件
public class LocalEvent extends ApplicationEvent {
public LocalEvent(Object source) {
super(source);
}
}
监听所有事件
public class ApplicationContextListener2 implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
System.out.println("事件类型" + applicationEvent.getClass().getName());
}
}
深入源码理解事件监听执行流程
创建容器对象
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
// refresh
refresh();
}
}
org.springframework.context.support.AbstractApplicationContext
refresh方法:去掉了部分源码,重点展示与事件和监听相关的代码
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
try {
// 初始化事件广播器
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 将容器中的监听器放入事件广播器中
// Check for listener beans and register them.
registerListeners();
// Last step: publish corresponding event.
// 初始化完成后刷新
finishRefresh();
}
catch (BeansException ex) {
}
finally {
}
}
}
initApplicationEventMulticaster 方法
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
// 获取 Bean 工厂
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断是否自定义了事件广播器
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 没有自定义事件处理器就创建 SimpleApplicationEventMulticaster 事件广播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
registerListeners 方法,将监听器添加到事件广播器中
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 在 bean 工厂中获取实现了 ApplicationListener 的监听器
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
// 事件广播器循环添加监听器
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishRefresh 初始化完成后刷新
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 发布 ContextRefreshedEvent 事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
根据事件类型来执行相应监听器的监听方法
SimpleApplicationEventMulticaster 中的 multicastEvent
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
// 获取事件类型
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 获取自定义任务执行器
Executor executor = getTaskExecutor();
// 循环监听器,如果自定义任务执行器不存在,就调用invokeListener()方法。看到最后是调用了 listener 的 onApplicationEvent 方法。
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
总结: 启动容器,获取监听器,将监听器添加到事件广播器中。当调用发布事件方法时,由事件广播器对事件进行广播。