Java-第十五部分-源码解读-监听器梳理

138 阅读2分钟

源码解读全文

监听器

  • IOC容器启动时,会装配EventListenerProcessor/DefaultEventListenerFactory
  • EventListenerProcessor,可以对BeanFactoryBean进行增强
  1. 工厂后置处理环节
  2. 所有Bean创建好后,进行监听方法的提取,封装成监听器
  • DefaultEventListenerFactory,负责创建监听器的工厂 image.png

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));
  • 遍历每一个方法,和事件监听工厂 image.png
  • 为方法创建一个监听器ApplicationListener<?> applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse);,并进行初始化
  1. 实际上是为每一个方法创造了一个适配器,把当前方法和BeanName分装到这个适配器中
  2. 可以起到监听的工程
  3. 收到事件后,通过这个适配器,调用该Bean的该方法
  • 实际上创造的为ApplicationListenerMethodAdapter
@Override
public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {
   return new ApplicationListenerMethodAdapter(beanName, type, method);
}

image.png

  • 将适配器加入到了容器中和事件多播器中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);
}
  • 事件保存在容器AnnotationConfigApplicationContextimage.png

事件派发

  • 最终调用AbstractApplicationContextpublishEvent
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;
   }
}