springboot 源码笔记
1.springAppication构造器
基于getSpringFactoriesInstances方法构造如下类(获取文件内容在META-INF/spring.factories文件中)
1.1 初始化ApplicationContextInitializer.class
# Application Context Initializers org.springframework.context.ApplicationContextInitializer=\ org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\ org.springframework.boot.context.ContextIdApplicationContextInitializer,\ org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\ org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
1.2 初始化ApplicationListener.class
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
2.run方法
StopWatch stopWatch = new StopWatch();//构造时间观察器 stopWatch.start();// 打印一个开始时间 ConfigurableApplicationContext context = null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty();// 配置headless 依据java.awt.headless SpringApplicationRunListeners listeners = getRunListeners(args);// 解析如下 // getSpringFactoriesInstances方法获取SpringApplicationRunListener.class对象->EventPublishingRunListener对象 // EventPublishingRunListener对象初始化时,构造器内会执行下面的逻辑 //SimpleApplicationEventMulticaster广播器初始化,并且将listener设置到广播器中 // 将上面获取到的EventPublishingRunListener对象对象添加到SpringApplicationRunListeners对象中 listeners.starting(); // 解析如下 // 调用EventPublishingRunListener对象的starting方法 // 将ApplicationStartingEvent广播出去 SimpleApplicationEventMulticaster->multicastEvent方法 // 调用getApplicationListeners方法获取所有listeners,然后循环广播 // 调用支持事件的listener的listener.onApplicationEvent(event);方法,驱动listener巡行 // 此处支持的listener如下 // org.springframework.boot.logging.LoggingApplicationListener, // org.springframework.boot.autoconfigure.BackgroundPreinitializer, // org.springframework.boot.context.config.DelegatingApplicationListener, // org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); // 创建一个DefaultApplicationArguments对象,构造器中构造了一个新的SOURCE对象 // 根据SOURCE对象的继承结构->SimpleCommandLinePropertySource->parse方法 // 如果args是–开头的,就加入OptionArg中,否则加入到NonOptionArg中 // CommandLinePropertySource构造其中commandLineArgs存入source ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); // 参照下面的prepareEnvironment方法分析 configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); // 打印banner context = createApplicationContext(); // 创建applicationContext // 添加AnnotationTypeFilter–>Component 添加AnnotationTypeFilter –> ManagedBean 添加AnnotationTypeFilter –> javax.inject.Named // 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); }
prepareEnvironment方法分析
private ConfigurableEnvironment prepareEnvironment( SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment ConfigurableEnvironment environment = getOrCreateEnvironment(); // 获取或者创建ConfigurableEnvironment 构造environment对象 继承AbstractEnvironment // AbstractEnvironment构造器中调用customizePropertySources方法 // StandardEnvironment对象:配置systemEnvironment systemProperties // StandardServletEnvironment对象:配置servletContextInitParams servletConfigInitParams jndiProperties configureEnvironment(environment, applicationArguments.getSourceArgs()); // 配置环境的信息 // configurePropertySources 配置PropertySources // commandLineArgs、servletConfigInitParams、servletContextInitParams、jndiProperties(如果存在)、 // systemProperties、systemEnvironment、defaultProperties(如果存在) // configureProfiles 配置Profiles // 至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。 // application-dev.properties:开发环境 application-test.properties:测试环境 application-prod.properties:生产环境 listeners.environmentPrepared(environment); // 通知所有的观察者,发送ApplicationEnvironmentPreparedEvent事件. // org.springframework.boot.context.config.ConfigFileApplicationListener, // org.springframework.boot.context.config.AnsiOutputApplicationListener, // org.springframework.boot.logging.LoggingApplicationListener, // org.springframework.boot.logging.ClasspathLoggingApplicationListener, // org.springframework.boot.autoconfigure.BackgroundPreinitializer, // org.springframework.boot.context.config.DelegatingApplicationListener, // org.springframework.boot.context.FileEncodingApplicationListener // bindToSpringApplication(environment); if (!this.isCustomEnvironment) { environment = new EnvironmentConverter(getClassLoader()) .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); } ConfigurationPropertySources.attach(environment); return environment; }
prepareContext分析
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { // 1. 上下文设置环境 context.setEnvironment(environment); // 2. 调用postProcessApplicationContext方法设置上下文的beanNameGenerator和resourceLoader(如果SpringApplication有的话) postProcessApplicationContext(context); // 3. 拿到之前实例化SpringApplication对象的时候设置的ApplicationContextInitializer,调用它们的initialize方法,对上下文做初始化 applyInitializers(context); // 4. contextPrepareds 是一个空实现 listeners.contextPrepared(context); // 5. 打印启动日志 if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans // 6. 日志往上下文的beanFactory中注册一个singleton的bean,bean的名字是springApplicationArguments,bean的实例是之前实例化的ApplicationArguments对象 context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); // 如果之前获取的printedBanner不为空,那么往上下文的beanFactory中注册一个singleton的bean,bean的名字是springBootBanner,bean的实例就是这个printedBanner if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } // Load the sources Set<Object> sources = getSources(); Assert.notEmpty(sources, "Sources must not be empty"); // 7. 调用load方法注册启动类的bean定义,也就是调用SpringApplication.run(Application.class, args);的类,SpringApplication的load方法内会创建BeanDefinitionLoader的对象,并调用它的load()方法 load(context, sources.toArray(new Object[sources.size()])); // 8. 调用listeners的contextLoaded方法,说明上下文已经加载,该方法先找到所有的ApplicationListener,遍历这些listener,如果该listener继承了ApplicationContextAware类,那么在这一步会调用它的setApplicationContext方法,设置context listeners.contextLoaded(context); }
# Environment Post Processors org.springframework.boot.env.EnvironmentPostProcessor=\ org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\ org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\ org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
1.SpringFactoriesLoader类
loadFactoryNames->loadSpringFactories->META-INF/spring.factories
位置:spring-boot-2.0.5.RELEASE-sources.jar目录下