SpringBoot源码学习(二) 发布启动事件

运行Spring应用程序

public ConfigurableApplicationContext run(String... args) {
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   // 配置无头属性, 设置该应用程序即使没有检测到显示器也允许启动
   configureHeadlessProperty();
   // 从`META-INF/spring.factories`文件集中获取SpringApplicationRunListener的子类listener
   SpringApplicationRunListeners listeners = getRunListeners(args);
   // 开启事件监听,通知监听者们(listener)执行相应操作
   listeners.starting();
   try {
      // 封装命令行参数
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      // 准备环境
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
      // 配置忽略信息
      configureIgnoreBeanInfo(environment);
      // 打印banner
      Banner printedBanner = printBanner(environment);
      // 创建应用上下文
      context = createApplicationContext();
      // 从`META-INF/spring.factories`文件集中获取SpringBootExceptionReporter的子类
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
      // 准备上下文
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      // 刷新上下
      refreshContext(context);
      // 刷新上下文后置处理
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
   }

   try {
      listeners.running(context);
   }
   catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
   }
   return context;
}

获取监听器

调用getRunListeners(args)方法,实例化一个SpringApplicationRunListeners对象。 通过getSpringFactoriesInstances方法读取META-INF/spring.factories进而实例化EventPublishingRunListener

/**
 * 从`META-INF/spring.factories`文件集中获取SpringApplicationRunListener的子类listener
 * @param args 命令行参数
 * @return
 */
private SpringApplicationRunListeners getRunListeners(String[] args) {
   Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
   // 实例化观察模式的目标类, 在实例化时绑定监听器(SpringApplicationRunListener子类)
   return new SpringApplicationRunListeners(logger,
         getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

注意: getSpringFactoriesInstances参数中的this,此方法将SpringApplication本身也传递过去了。

EventPublishingRunListener初始化

private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
      ClassLoader classLoader, Object[] args, Set<String> names) {
   List<T> instances = new ArrayList<>(names.size());
   // 此时`names`只有`org.springframework.boot.context.event.EventPublishingRunListener`一个元素
   for (String name : names) {
      try {
         Class<?> instanceClass = ClassUtils.forName(name, classLoader);
         Assert.isAssignable(type, instanceClass);
         // 行参parameterTypes此时为`new Class<?>[] { SpringApplication.class, String[].class }`
         Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
         // 实参此时为 `this, args`,this为SpringApplication实例, args为命令行参数
         T instance = (T) BeanUtils.instantiateClass(constructor, args);
         instances.add(instance);
      }
      catch (Throwable ex) {
         throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
      }
   }
   return instances;
}

调用getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args)通过反射实例化EventPublishingRunListener

EventPublishingRunListener实例化

public EventPublishingRunListener(SpringApplication application, String[] args) {
   this.application = application;
   // 命令行参数
   this.args = args;
   // 事件多播器
   this.initialMulticaster = new SimpleApplicationEventMulticaster();
   /**
    * org.springframework.boot.devtools.restart.RestartApplicationListener,
    * org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
    * org.springframework.boot.context.config.ConfigFileApplicationListener,
    * org.springframework.boot.context.config.AnsiOutputApplicationListener,
    * org.springframework.boot.context.logging.LoggingApplicationListener,
    * org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,
    * org.springframework.boot.autoconfigure.BackgroundPreinitializer,
    * org.springframework.boot.context.config.DelegatingApplicationListener,
    * org.springframework.boot.builder.ParentContextCloserApplicationListener,
    * org.springframework.boot.devtools.logger.DevToolsLogFactory$Listener,
    * org.springframework.boot.ClearCachesApplicationListener,
    * org.springframework.boot.context.FileEncodingApplicationListener,
    * org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
    */
   for (ApplicationListener<?> listener : application.getListeners()) {
      this.initialMulticaster.addApplicationListener(listener);
   }
}

依赖关系图谱

SimpleApplicationEventMulticaster

SimpleApplicationEventMulticaster实例化

此源码为AbstractApplicationEventMulticaster中方法。

@Override
public void addApplicationListener(ApplicationListener<?> listener) {
   synchronized (this.defaultRetriever) {
      // Explicitly remove target for a proxy, if registered already,
      // in order to avoid double invocations of the same listener.
      // 删除代理的目标(如果已注册),以避免重复调用同一侦听器,暂时没有发现有哪个监听器符合条件
      Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
      if (singletonTarget instanceof ApplicationListener) {
         this.defaultRetriever.applicationListeners.remove(singletonTarget);
      }
       
      // 添加目标 
      this.defaultRetriever.applicationListeners.add(listener);
      // 清理检索缓存 
      this.retrieverCache.clear();
   }
}

启动监听器

listeners.starting();

void starting() {
   // org.springframework.boot.context.event.EventPublishingRunListener
   for (SpringApplicationRunListener listener : this.listeners) {
      listener.starting();
   }
}

调用EventPublishingRunListener中的starting()方法。

@Override
public void starting() {
   // 构造EventObject事件, source为application并广播事件,通知各个监听器
   this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
}

广播Event

@Override
public void multicastEvent(ApplicationEvent event) {
   // 过滤监听器,为其广播事件。resolveDefaultEventType(event)除了`org.springframework.http.client.PublisherEntity`和`org.springframework.context.PayloadApplicationEvent`其余返回new ResolvableType(clazz)
   multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   Executor executor = getTaskExecutor();
   /**
    * 返回与给定事件类型匹配的ApplicationListeners的集合。不匹配的监听器会被排除在外。
    * org.springframework.boot.devtools.restart.RestartApplicationListener,
    * org.springframework.boot.context.logging.LoggingApplicationListener,
    * org.springframework.boot.autoconfigure.BackgroundPreinitializer,
    * org.springframework.boot.context.config.DelegatingApplicationListener,
    * org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
    */
   for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      if (executor != null) {
         executor.execute(() -> invokeListener(listener, event));
      }
      else {
         // 用给定的事件调用给定的监听器。
         invokeListener(listener, event);
      }
   }
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
   ErrorHandler errorHandler = getErrorHandler();
   if (errorHandler != null) {
      try {
         doInvokeListener(listener, event);
      }
      catch (Throwable err) {
         errorHandler.handleError(err);
      }
   }
   else {
      doInvokeListener(listener, event);
   }
}

@SuppressWarnings({"rawtypes", "unchecked"})
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.isTraceEnabled()) {
            logger.trace("Non-matching event type for listener: " + listener, ex);
         }
      }
      else {
         throw ex;
      }
   }
}
posted @ 2021-01-21 16:07  Chinda  阅读(333)  评论(0编辑  收藏  举报