启动流程:初始化
1、SpringApplication.run(SpringBootMainApplication.class, args);
2、(new SpringApplication(primarySources)).run(args);
3、new SpringApplication:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.sources = new LinkedHashSet(); this.bannerMode = Mode.CONSOLE; this.logStartupInfo = true; this.addCommandLineProperties = true; this.addConversionService = true; this.headless = true; this.registerShutdownHook = true; this.additionalProfiles = new HashSet(); this.isCustomEnvironment = false; this.lazyInitialization = false; this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet(Arrays.asList(primarySources)); this.webApplicationType = WebApplicationType.deduceFromClasspath(); this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class)); this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass = this.deduceMainApplicationClass(); } |
WebApplicationType.deduceFromClasspath()用来判断DispatcherHandler、DispatcherServlet、ServletContainer是否是web应用;
getSpringFactoriesInstances(ApplicationContextInitializer.class)从META-INF/spring.factories文件中筛选出ApplicationContextInitializer列表;
getSpringFactoriesInstances(ApplicationListener.class)从this.getSpringFactoriesInstances中筛选出ApplicationListener列表;
deduceMainApplicationClass()则查找带有main方法的类;
(关键方法是:SpringFactoriesLoader.loadSpringFactories,且spring.factories都放在Map<String, List<String>>中)
启动流程:启动
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList(); this.configureHeadlessProperty(); SpringApplicationRunListeners listeners = this.getRunListeners(args); listeners.starting(); Collection exceptionReporters; try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments); this.configureIgnoreBeanInfo(environment); Banner printedBanner = this.printBanner(environment); context = this.createApplicationContext(); exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context); this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); this.refreshContext(context); this.afterRefresh(context, applicationArguments); stopWatch.stop(); if (this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } listeners.started(context); this.callRunners(context, applicationArguments); } catch (Throwable var10) { this.handleRunFailure(context, var10, exceptionReporters, listeners); throw new IllegalStateException(var10); } try { listeners.running(context); return context; } catch (Throwable var9) { this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null); throw new IllegalStateException(var9); } } |
this.getRunListeners还是把从META-INF/spring.factories中读取到的SpringApplicationRunListener列表取出来;
listeners.starting则是遍历SpringApplicationRunListener列表,并调用其starting()方法;
this.prepareEnvironment就是创建各种Environment对象,下面是关键代码:
private ConfigurableEnvironment getOrCreateEnvironment() { |
createApplicationContext则是根据类型不同,创建对应的Context对象,下面是关键代码:
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch(this.webApplicationType) { case SERVLET: contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext"); break; case REACTIVE: contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext"); break; default: contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext"); } } catch (ClassNotFoundException var3) { throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3); } }
return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass); } |
prepareContext方法分别调用了applyInitializers、contextPrepared、contextLoaded方法,来分别对initializer、listener进行初始化:
protected void applyInitializers(ConfigurableApplicationContext context) { Iterator var2 = this.getInitializers().iterator(); while(var2.hasNext()) { ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next(); Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); } }
void contextPrepared(ConfigurableApplicationContext context) { Iterator var2 = this.listeners.iterator(); while(var2.hasNext()) { SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next(); listener.contextPrepared(context); } }
void contextLoaded(ConfigurableApplicationContext context) { Iterator var2 = this.listeners.iterator(); while(var2.hasNext()) { SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next(); listener.contextLoaded(context); } } |
refreshContext关键代码如下,负责对IOC容器中的Bean等一系列组件进行初始化,这里才是Bean等初始化的地方:
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } } |
started(context)与running(context)都是遍历SpringApplicationRunListener,然后分别调用其started、running方法:
void started(ConfigurableApplicationContext context) { Iterator var2 = this.listeners.iterator(); while(var2.hasNext()) { SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next(); listener.started(context); } }
void running(ConfigurableApplicationContext context) { Iterator var2 = this.listeners.iterator(); while(var2.hasNext()) { SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next(); listener.running(context); } } |