🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ~~~ public SpringApplication(Class<?>... primarySources) { this(null, primarySources); } @SuppressWarnings({ "unchecked", "rawtypes" }) public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; //判断primarySources不能为空 Assert.notNull(primarySources, "PrimarySources must not be null"); //将primarySources放入SpringApplication的全局变量primarySources,Set集合中 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); //从类路径中推断应用程序类型放到SpringApplication的全局变量webApplicationType this.webApplicationType = WebApplicationType.deduceFromClasspath(); //从META-INF/spring.factories文件中获取ApplicationContextInitializer接口的实现类并利用反射创建对象返回放入SpringApplication的全局变量initializers,List集合中 setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); //同上,也是从META-INF/spring.factories文件中获取ApplicationListener接口的实现类并利用反射创建对象返回放入SpringApplication的全局变量listeners,List集合中 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); //通过获取当前调用栈,找到入口方法main所在的类,放入SpringApplication的全局变量mainApplicationClass this.mainApplicationClass = deduceMainApplicationClass(); } ~~~ ~~~ public ConfigurableApplicationContext run(String... args) { //StopWatch是org.springframework.util的工具类,可以用来方便的记录程序的运行时间 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); //设置系统属性java.awt.headless为true configureHeadlessProperty(); //从META-INF/spring.factories文件中得到SpringApplicationRunListeners接口的所有实现类 //然后通过构造方法创建SpringApplicationRunListeners对象。参数就是获取到的接口实现类集合 //该对象持有一个SpringApplicationRunListener对象的集合,并且封装了SpringApplicationRunListener对象对应的方法,方便统一管理Listener SpringApplicationRunListeners listeners = getRunListeners(args); //广播事件ApplicationStartingEvent listeners.starting(); try { //将args参数进一步封装成ApplicationArguments ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); //构建环境(Environment) ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); //设置系统属性spring.beaninfo.ignore configureIgnoreBeanInfo(environment); //打印banner Banner printedBanner = printBanner(environment); //根据环境类型创建容器 context = createApplicationContext(); //SpringApplication启动错误的自定义报告 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); } //发布事件ApplicationStartedEvent listeners.started(context); //回调ApplicationRunner接口以及CommandLineRunner接口的run方法 callRunners(context, applicationArguments); } catch (Throwable ex) { //发布ApplicationFailedEvent、ExitCodeEvent事件,异常报告 handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { //发布事件ApplicationReadyEvent listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; } ~~~