此文已由作者赵计刚薪授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
1 public ConfigurableApplicationContext run(String... args) { 2 StopWatch stopWatch = new StopWatch(); //设置计时器 3 stopWatch.start(); //记录当前时间 4 ConfigurableApplicationContext context = null; 5 configureHeadlessProperty(); //设置java.awt.headless为true或false 6 SpringApplicationRunListeners listeners = getRunListeners(args);//获取事件发布器(控制所有事件的执行时机) 7 listeners.started(); //事件发布器发布ApplicationStartedEvent事件,所有监听了该事件的ApplicationListener实现类执行逻辑 8 try { 9 context = doRun(listeners, args); 10 stopWatch.stop(); //计时结束(记录总共花了多少时间) 11 if (this.logStartupInfo) { 12 new StartupInfoLogger(this.mainApplicationClass) 13 .logStarted(getApplicationLog(), stopWatch); 14 } 15 return context; 16 } 17 catch (Throwable ex) { 18 handleRunFailure(context, listeners, ex); 19 throw new IllegalStateException(ex); 20 } 21 }
1 private ConfigurableApplicationContext doRun(SpringApplicationRunListeners listeners, 2 String... args) { 3 ConfigurableApplicationContext context; 4 // Create and configure the environment 5 ConfigurableEnvironment environment = getOrCreateEnvironment(); //创建Environment 6 configureEnvironment(environment, args); //配置Environment(包括配置要使用的PropertySource和Profile) 7 listeners.environmentPrepared(environment); //事件发布器发布ApplicationEnvironmentPreparedEvent事件,所有监听了该事件的ApplicationListener执行相应逻辑 8 if (isWebEnvironment(environment) && !this.webEnvironment) { 9 environment = convertToStandardEnvironment(environment); 10 } 11 12 if (this.bannerMode != Banner.Mode.OFF) { 13 printBanner(environment); 14 } 15 16 // Create, load, refresh and run the ApplicationContext 17 context = createApplicationContext(); //创建ApplicationContext容器 18 context.setEnvironment(environment); //设置Environment到容器 19 postProcessApplicationContext(context); 20 applyInitializers(context); //执行所有的ApplicationContextInitializer的initial方法,对创建出来的ApplicationContext容器进行初始化 21 listeners.contextPrepared(context); 22 if (this.logStartupInfo) { 23 logStartupInfo(context.getParent() == null); 24 logStartupProfileInfo(context); 25 } 26 27 // Add boot specific singleton beans 28 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); 29 context.getBeanFactory().registerSingleton("springApplicationArguments", 30 applicationArguments); 31 32 // Load the sources 33 Set<Object> sources = getSources(); 34 Assert.notEmpty(sources, "Sources must not be empty"); 35 load(context, sources.toArray(new Object[sources.size()])); //将之前通过@EnableAutoConfiguration的所有配置以及其他形式的IOC容器加载到已经准备完毕的ApplicationContext 36 listeners.contextLoaded(context); //事件发布器将所有的ApplicationListener注册给当前的ApplicationContext,之后发布ApplicationPreparedEvent事件 37 38 // Refresh the context 39 refresh(context); //刷新ApplicationContext 40 if (this.registerShutdownHook) { 41 try { 42 context.registerShutdownHook(); 43 } 44 catch (AccessControlException ex) { 45 // Not allowed in some environments. 46 } 47 } 48 afterRefresh(context, applicationArguments); 49 listeners.finished(context, null); 50 return context; 51 }
步骤总结:
以上红色部分就是核心步骤!
参考:
http://www.jianshu.com/p/692b10aef052
http://zhaox.github.io/java/2016/03/22/spring-boot-start-flow
《springboot揭秘-快速构建微服务体系》
更多网易技术、产品、运营经验分享请点击。