启动流程图如下:
相关Event(org.springframework.boot.context.event.SpringApplicationEvent的子类),这些Event是很好的标志,告诉我们程序执行到哪一步了,如下
ApplicationStartingEvent:在Environment和ApplicationContext可用之前 & 在ApplicationListener注册之后发布。
ApplicationContextInitializedEvent:在bean定义加载之前 & ApplicationContextInitializers被调用之后 & ApplicationContext开始准备之后发布
ApplicationPreparedEvent:在ApplicationContext完全准备好并且没有刷新之前发布,此时bean定义即将加载,Environment已经准备好被使用。
ApplicationStartedEvent:在ApplicationContext刷新之后,调用ApplicationRunner和CommandLineRunner之前发布
ApplicationReadyEvent:应用已经准备好接受请求时发布。
第一步,先进入启动类
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
第二步,执行run方法,实际上执行的是【org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])】
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return run(new Class<?>[] { primarySource }, args); } public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { // 初始化SpringApplication,然后执行run方法 return new SpringApplication(primarySources).run(args); }
1. new SpringApplication【org.springframework.boot.SpringApplication#SpringApplication(org.springframework.core.io.ResourceLoader, java.lang.Class<?>...)】
public SpringApplication(Class<?>... primarySources) { this(null, primarySources); } public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = deduceMainApplicationClass(); }
2. run【org.springframework.boot.SpringApplication#run(java.lang.String...)】
public ConfigurableApplicationContext run(String... args) { // 一个计算耗时小工具 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); // 获取监听器 SpringApplicationRunListeners listeners = getRunListeners(args); // 监听器启动 listeners.starting(); try { // 创建默认应用参数 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 准备环境 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 处理要忽略的bean信息 configureIgnoreBeanInfo(environment); // 打印Banner Banner printedBanner = printBanner(environment); // 获取应用上下文 context = createApplicationContext(); // 获取异常报告实例列表 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; }
StopWatch stopWatch = new StopWatch("Test ABC"); stopWatch.start("Task A"); for (int i = 0; i < 10; i++){ } stopWatch.stop(); stopWatch.start("Task B"); for (int i = 0; i < 5; i++){ } stopWatch.stop(); stopWatch.start("Task C"); for (int i = 0; i < 15; i++){ } stopWatch.stop(); System.out.println(stopWatch.prettyPrint());
输出:
private SpringApplicationRunListeners getRunListeners(String[] args) { Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class }; // 返回一个SpringApplicationRunListener的集合包装类 return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args)); } private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { ClassLoader classLoader = getClassLoader(); // 使用Set集合确保name是唯一的;调用SpringFactoriesLoader.loadFactoryNames,使用给定的类加载器加载给定类型工厂实现的完全限定类名 Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); // 根据给的Class、类加载器、完全限定类型列表已经相关参数,根据反射创建实例列表 List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; } @SuppressWarnings("unchecked") private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) { List<T> instances = new ArrayList<>(names.size()); for (String name : names) { try { Class<?> instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes); T instance = (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex); } } return instances; }
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // 根据webApplicationType,决定创建StandardServletEnvironment还是StandardReactiveWebEnvironment还是StandardEnvironment ConfigurableEnvironment environment = getOrCreateEnvironment(); // 配置属性文件和激活的环境(spring.profiles.active所配) configureEnvironment(environment, applicationArguments.getSourceArgs()); // 将ConfigurationPropertySource附加到指定环境下 ConfigurationPropertySources.attach(environment); // 监听 listeners.environmentPrepared(environment); // 绑定环境到应用 bindToSpringApplication(environment); if (!this.isCustomEnvironment) { environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); } ConfigurationPropertySources.attach(environment); return environment; }
// 根据应用类型创建不同的上下文 protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { // 设置environment context.setEnvironment(environment); // 相关额外的处理 postProcessApplicationContext(context); applyInitializers(context); // 派发ApplicationContextInitializedEvent事件,表示应用正在启动,上下文正在准备并且一系列Initializer已经调用 listeners.contextPrepared(context); if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); beanFactory.registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { beanFactory.registerSingleton("springBootBanner", printedBanner); } if (beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory) beanFactory) .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.lazyInitialization) { context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor()); } // Load the sources Set<Object> sources = getAllSources(); Assert.notEmpty(sources, "Sources must not be empty"); load(context, sources.toArray(new Object[0])); // 监听上下文,派发ApplicationPreparedEvent事件,表示应用正在启动,上下文已经准备好刷新了 listeners.contextLoaded(context); } protected void postProcessApplicationContext(ConfigurableApplicationContext context) { if (this.beanNameGenerator != null) { // 注册注解工具类 context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, this.beanNameGenerator); } if (this.resourceLoader != null) { if (context instanceof GenericApplicationContext) { // 设置resourceLoader ((GenericApplicationContext) context).setResourceLoader(this.resourceLoader); } if (context instanceof DefaultResourceLoader) { ((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader()); } } if (this.addConversionService) { // 设置ConversionService context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance()); } }
private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } } protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); } public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 为上下文刷新做准备 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 告诉子类刷新内部bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 准备在这个上下文要用的bean工厂 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 允许在上下文子类中对bean工厂进行后续处理 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 执行上下文中已注册的bean工厂后置处理器 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册拦截bean创建过程的后置处理器 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 初始化此上下文的消息源 initMessageSource(); // Initialize event multicaster for this context. // 初始化事件派发器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 初始化子类实现的其它特殊bean onRefresh(); // Check for listener beans and register them. // 检查并注册侦听器bean registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化所有剩余的(非延迟初始化)单实例bean finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 最后,发布对应的事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset ‘active‘ flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring‘s core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
public void started(ConfigurableApplicationContext context) { context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context)); }
public void running(ConfigurableApplicationContext context) { context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context)); }
原文:https://www.cnblogs.com/LUA123/p/11720686.html