文章目录

  • ​​1.实例代码​​
  • ​​2.源码分析​​
  • ​​2.1 添加后置处理器源码解析​​
  • ​​2.2 发送事件源码分析​​
  • ​​3.总结​​

1.实例代码

Spring Event 源码 (四) (事件以及监听器的源码解析)_初始化

@Configuration
@ComponentScan("com.atguigu.event")
public class EventConfig {
}

监听器

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
// 监听器如何感知到事件的:
// ApplicationEvent 和 Payload
// getApplicationEventMulticaster: 获得多播器, 发送事件
// 观察者模式: 将所有的事件监听器拿到, 矮个遍历, 调用onApplicationEvent()方法

// 事件派发: 遍历监听器, 调用onApplicationEvent()方法
// 发布事件触发
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println(event);
}
}

服务代码

@Component
public class UserService {
// EventListenerMethodProcessor, DefaultEventListenerFactory
// 后置处理和初始化
// SmartInitializingSingleton: 工厂后置处理环节, 执行增强和所有Bean完全创建好后执行初始化
// 后置增强环节: EventListenerMethodProcessor.postProcessBeanFactory(): 拿到所有的EventListenerFactory, 排序
// 初始化环节: afterSingletonsInstantiated():拿到容器中所有的组件, 处理这个组件
// 1.找到@EventListener 方法
// 2.遍历每一个方法: 拿到DefaultEventListenerFactory, 当前方法, beanName 封装到适配器中ApplicationListenerMethodAdapter
// 工厂的作用为创造适配器: 适配器是一个监听器, 多播器注册监听器, 容器注册监听器, 事件派发给的是适配器, 适配器反射调用组件的事件监听方法
// 标了@EventListener 注解, 就创建适配器, 适配器反射调用方法
// EventListenerMethodProcessor这个后置处理器为每一个监听方法创建一个监听器组件(适配器)

// 发布器和监听器
// 感知的对象
@EventListener(classes = ApplicationEvent.class)
public void listener(ApplicationEvent event){
System.out.println("UserService : " + event);

}
}

主类

public class MainApplication {
public static void main(String[] args) {
/**
* 事件的发布和监听机制的原理:
* 获取到EventMulticaster: 事件派发器
* 事件派发器: getApplicationEventMulticaster(): refresh(): initApplicationEventMulticaster()
* 容器中有哪些监听器: refresh(): registerListener()
*
* @EventListener:
* EventListenerMethodProcessor->SmartInitializingSingleton, 单实例Bean创建完成后执行
*/
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
// 发布事件
context.publishEvent(new ApplicationEvent("1") {
});
context.close();
// ContextRefreshedEvent,source,ContextClosedEvent
}
}

发布事件

Spring Event 源码 (四) (事件以及监听器的源码解析)_监听器_02

2.源码分析

  • 创建过程
  • 运行过程

2.1 添加后置处理器源码解析

添加后置处理器为创建过程

在ioc容器启动(this()方法)的时候, 会加载EventListenerMethodProcessor 这个工厂后置处理器

Spring Event 源码 (四) (事件以及监听器的源码解析)_初始化_03

这个后置处理器实现了​​SmartInitializingSingleton​​​和 ​​BeanFactoryPostProcessor​​ 两个接口

​SmartInitializingSingleton​​: 工厂后置处理环节, 执行增强和所有Bean完全创建好后执行初始化

  • 后置增强环节: EventListenerMethodProcessor.postProcessBeanFactory(): 拿到所有的EventListenerFactory, 并排序
  • 初始化环节: afterSingletonsInstantiated():拿到容器中所有的组件, 处理这个组件

Spring Event 源码 (四) (事件以及监听器的源码解析)_1024程序员节_04

postProcessBeanFactory: 拿到所有的EventListenerFactory, 并进行排序

Spring Event 源码 (四) (事件以及监听器的源码解析)_初始化_05

afterSingletonsInstantiated: 拿到容器中所有的组件, 处理这个组件

Spring Event 源码 (四) (事件以及监听器的源码解析)_观察者模式_06


​processBean()​

private void processBean(final String beanName, final Class<?> targetType) {
if (!this.nonAnnotatedClasses.contains(targetType) &&
AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
!isSpringContainerClass(targetType)) {

Map<Method, EventListener> annotatedMethods = null;
try {
annotatedMethods = MethodIntrospector.selectMethods(targetType,
(MethodIntrospector.MetadataLookup<EventListener>) method ->
AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
}
catch (Throwable ex) {
// An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
}
}

if (CollectionUtils.isEmpty(annotatedMethods)) {
this.nonAnnotatedClasses.add(targetType);
if (logger.isTraceEnabled()) {
logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
}
}
else {
// Non-empty set of methods
ConfigurableApplicationContext context = this.applicationContext;
Assert.state(context != null, "No ApplicationContext set");
List<EventListenerFactory> factories = this.eventListenerFactories;
Assert.state(factories != null, "EventListenerFactory List not initialized");
for (Method method : annotatedMethods.keySet()) {
for (EventListenerFactory factory : factories) {
if (factory.supportsMethod(method)) {
Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
ApplicationListener<?> applicationListener =
factory.createApplicationListener(beanName, targetType, methodToUse);
if (applicationListener instanceof ApplicationListenerMethodAdapter) {
((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
}
context.addApplicationListener(applicationListener);
break;
}
}
}
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
beanName + "': " + annotatedMethods);
}
}
}
}

拿到​​DefaultEventListenerFactory​​, 然后封装进适配器中

Spring Event 源码 (四) (事件以及监听器的源码解析)_监听器_07

  1. 找到@EventListener 方法
  2. 遍历每一个方法: 拿到DefaultEventListenerFactory, 当前方法, beanName 封装到适配器中ApplicationListenerMethodAdapter
  3. 工厂的作用为创造适配器: 适配器是一个监听器, 多播器注册监听器, 容器注册监听器, 事件派发给的是适配器, 适配器反射调用组件的事件监听方法。
    标了@EventListener 注解, 就创建适配器, 适配器反射调用方法。

EventListenerMethodProcessor这个后置处理器为每一个监听方法创建一个监听器组件(适配器)

2.2 发送事件源码分析

发送事件过程为运行事件过程

Spring Event 源码 (四) (事件以及监听器的源码解析)_观察者模式_08

Spring Event 源码 (四) (事件以及监听器的源码解析)_观察者模式_09

Spring Event 源码 (四) (事件以及监听器的源码解析)_1024程序员节_10

观察者模式: for 循环

Spring Event 源码 (四) (事件以及监听器的源码解析)_1024程序员节_11

Spring Event 源码 (四) (事件以及监听器的源码解析)_初始化_12

调用每一个监听器的​​onApplicationEvent​​方法

3.总结

事件机制: 1.创建后置处理器, 后置处理器可以创建适配器(监听器) 2.在发布事件的时候, 触发监听器的方法

事件机制简而言之就是观察者模式。不过之前有后置处理器的干预, 然后构建了一个后置处理器参与的观察者模式。