源码解读全文
监听器
- IOC容器启动时,会装配
EventListenerProcessor/DefaultEventListenerFactory
EventListenerProcessor
,可以对BeanFactory
和Bean
进行增强
- 工厂后置处理环节
- 所有
Bean
创建好后,进行监听方法的提取,封装成监听器
DefaultEventListenerFactory
,负责创建监听器的工厂
postProcessBeanFactory
- 获取所有的
EventListenerFactory
,并进行排序
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
Map<String, EventListenerFactory> beans = beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
List<EventListenerFactory> factories = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(factories);
this.eventListenerFactories = factories;
}
afterSingletonsInstantiated
- 为每个监听方法,创建了监听器
- 获取所有组件
String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
- 进行处理
processBean(beanName, type);
- 找到所有组件中所有
@EventListner
标注的方法,annotatedMethods = MethodIntrospector.selectMethods(targetType, (MethodIntrospector.MetadataLookup<EventListener>) method -> AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
- 遍历每一个方法,和事件监听工厂
- 为方法创建一个监听器
ApplicationListener<?> applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse);
,并进行初始化
- 实际上是为每一个方法创造了一个适配器,把当前方法和
BeanName
分装到这个适配器中- 可以起到监听的工程
- 收到事件后,通过这个适配器,调用该
Bean
的该方法
- 实际上创造的为
ApplicationListenerMethodAdapter
@Override
public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {
return new ApplicationListenerMethodAdapter(beanName, type, method);
}
- 将适配器加入到了容器中和事件多播器中
context.addApplicationListener(applicationListener);
public void addApplicationListener(ApplicationListener<?> listener) {
Assert.notNull(listener, "ApplicationListener must not be null");
if (this.applicationEventMulticaster != null) {
//多播器,会向这个监听器派发事件
this.applicationEventMulticaster.addApplicationListener(listener);
}
this.applicationListeners.add(listener);
}
- 事件保存在容器
AnnotationConfigApplicationContext
中
事件派发
- 最终调用
AbstractApplicationContext
的publishEvent
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
// 类型转换
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else { //支持任意类型,封装成 PayloadApplicationEvent
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);
}
}
}
multicastEvent
,观察者模式,遍历保存的监听器,进行事件执行
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
Executor executor = getTaskExecutor();
// 需要类型匹配
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
- 最终调用
listener.onApplicationEvent(event);
,通过反射进行执行
监听方法最终会被封装成一个
listener
对象
ApplicationListenerDetector
- 处理为监听器的
Bean
- 在
Bean
初始化后的,后置处理过程wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
调用ApplicationListenerDetector.postProcessAfterInitialization
,进行监听器的处理 postProcessAfterInitialization
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) { //是否为一个监听器
// singletonNames 在实例化Bean之后`postProcessMergedBeanDefinition`进行保存是否为单例
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) { //如果该Bean是监听器且是单例就加入
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
//...
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
自定义时间监听器
MyListener监听器
@Component
public class MyListener {
public MyListener() {
System.out.println("MyListener");
}
@EventListener(MessageEvent.class)
public void listenMessage(MessageEvent messageEvent) {
System.out.println("listenMessage");
System.out.println(messageEvent.getSource());
}
@EventListener(PayloadApplicationEvent.class)
public void listenObject(PayloadApplicationEvent<Object> event) {
System.out.println(event.getSource());
}
}
AppListener通过接口实现监听器
@Component
public class AppListener implements ApplicationListener<MessageEvent> {
@Override
public void onApplicationEvent(MessageEvent event) {
System.out.println("AppListener");
System.out.println(event);
}
}
MessageEvent事件
public class MessageEvent extends ApplicationEvent implements Serializable {
private static final long serialVersionUID = 0L;
@Override
public String toString() {
return "MessageEvent{" +
"source=" + source +
'}';
}
public MessageEvent(Object source) {
super(source);
}
public MessageEvent(Object source, Clock clock) {
super(source, clock);
}
}
AppEventPulisher派发器
@Component
public class AppEventPulisher implements ApplicationEventPublisherAware {
ApplicationEventPublisher applicationEventPublisher;
public void publish(Object o) {
applicationEventPublisher.publishEvent(o);
}
public void publish(ApplicationEvent event) {
applicationEventPublisher.publishEvent(event);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}