初始化SpringApplication
springboot程序的启动,就是实例化SpringApplication,然后调用run方法。
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
实例化时执行如下初始化方法
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
//判断是否web环境
this.webEnvironment = deduceWebEnvironment();
//加载初始化器
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//加载监听器
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//定位main函数的类
this.mainApplicationClass = deduceMainApplicationClass();
}
其中getSpringFactoriesInstances方法,负责从spring.factory文件中读取出要加载的类,并且实例化。(细节见源码,不复杂)
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
//从spring.factory中读取要加载的类
Set<String> names = new LinkedHashSet<String>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
//进行实例化
List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
//根据取出的类中,@Order的顺序进行排序
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
特别备注一下,从spring.factory中加载的ApplicationContextInitializer有:
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
org.springframework.boot.context.ContextIdApplicationContextInitializer
org.springframework.boot.context.config.DelegatingApplicationContextInitializer
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
加载的ApplicationListener有:
org.springframework.boot.autoconfigure.BackgroundPreinitializer
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.liquibase.LiquibaseServiceLocatorApplicationListener
org.springframework.boot.logging.ClasspathLoggingApplicationListener
org.springframework.boot.logging.LoggingApplicationListener
org.springframework.cloud.bootstrap.BootstrapApplicationListener
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener
org.springframework.cloud.context.restart.RestartListener
启动SpringApplication
启动过程如下
public ConfigurableApplicationContext run(String... args) {
//计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
//获取应用启动过程的监听器,SpringApplicationRunListener(注意不是ApplicationListener)
SpringApplicationRunListeners listeners = getRunListeners(args);
//触发监听器
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//初始化环境变量,触发监听器
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
//打印自定义banner
Banner printedBanner = printBanner(environment);
//实例化容器(AnnotationConfigEmbeddedWebApplicationContext)
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
//容器前期准备
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//刷新容器,注册钩子
refreshContext(context);
//执行容器中所有的ApplicationRunner和CommandLineRunner
afterRefresh(context, applicationArguments);
//触发监听器,hammerhead关闭和配置中心的连接
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
SpringApplicationRunListener也是从spring.factory中获取,具体如下。EventPublishingRunListener在实例化时,传入了SpringApplication获取的所有ApplicationListener,然后在调用starting方法时,发出ApplicationStartedEvent,让所有ApplicationListener处理(注意并非所有listener都会处理该事件);ImmutableConfigRunListener触发时hammerhead开始介入,获取配置文件。
org.springframework.boot.context.event.EventPublishingRunListener
com.cmbchina.drift.hammerhead.client.spring.ImmutableConfigRunListener
prepareEnvironment方法创建并配置了环境
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
//创建StandardServletEnvironment实例
ConfigurableEnvironment environment = getOrCreateEnvironment();
//设置启动参数,设置有效的profile
configureEnvironment(environment, applicationArguments.getSourceArgs());
//触发监听器,广播事件,此处hammerhead开始打日志
listeners.environmentPrepared(environment);
if (!this.webEnvironment) {
environment = new EnvironmentConverter(getClassLoader())
.convertToStandardEnvironmentIfNecessary(environment);
}
return environment;
}
createApplicationContext方法创建了容器,实例化的是AnnotationConfigEmbeddedWebApplicationContext,实例化时会创建AnnotatedBeanDefinitionReader实例,调用AnnotationConfigUtils.registerAnnotationConfigProcessors方法,给容器注册了多个后置处理器,还有AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
注册的后置处理器包括
ConfigurationClassPostProcessor
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor
EventListenerMethodProcessor
DefaultEventListenerFactory
prepareContext方法对容器进行前期准备
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
//设置环境
context.setEnvironment(environment);
//设置容器的beanNameGenerator和resourceLoader
postProcessApplicationContext(context);
//之前获取的ApplicationContextInitializer全部执行(参数是容器)
applyInitializers(context);
//监听器处理事件
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
//把执行参数的实例注册到容器
context.getBeanFactory().registerSingleton("springApplicationArguments",applicationArguments);
if (printedBanner != null) {
context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
}
// Load the sources
Set<Object> sources = getSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[sources.size()]));
//ApplicationContext中获取的所有ApplicationListener,实现了ApplicationContextAware接口的把容器set进去
//把所有ApplicationListener写入容器中
listeners.contextLoaded(context);
}
refreshContext和afterRefresh流程涉及容器逻辑,会放在另一篇笔记中。
SpringApplication状态处理
SpringApplicationRunListener用于在SpringApplication处于不同生命周期。SpringBoot自己的实现为EventPublishingRunListener,每个生命周期会广播事件,然后依赖ApplicationListener处理这些事件。
生命周期---对应事件:
- starting---ApplicationStartedEvent
- environmentPrepared---ApplicationEnvironmentPreparedEvent
- contextPrepared---无
- contextLoaded---ApplicationPreparedEvent
- finished---ApplicationFailedEvent、ApplicationReadyEvent
starting
无
environmentPrepared
1、BackgroundPreinitializer
会启动一个线程异步的进行预初始化,可以看到各种转换都在这里初始化,但是初始化后的东西没有引用的地方,不是很理解为什么要预初始化
private void performPreinitialization() {
try {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
runSafely(new MessageConverterInitializer());
runSafely(new MBeanFactoryInitializer());
runSafely(new ValidationInitializer());
runSafely(new JacksonInitializer());
runSafely(new ConversionServiceInitializer());
preinitializationComplete.countDown();
}
public void runSafely(Runnable runnable) {
try {
runnable.run();
}
catch (Throwable ex) {
// Ignore
}
}
}, "background-preinit");
thread.start();
}...
}
2、FileEncodingApplicationListener
比较file.encoding和spring.mandatoryFileEncoding是否一致,不一致会中断启动
3、AnsiOutputApplicationListener
控制彩色输出的,意义不大
4、ConfigFileApplicationListener
ConfigFileApplicationListener本身实现了EnvironmentPostProcessor接口,处理事件时,从spring.factory中取出所有的EnvironmentPostProcessor实现类,加上自己,触发所有的EnvironmentPostProcessor。
private void onApplicationEnvironmentPreparedEvent(
ApplicationEnvironmentPreparedEvent event) {
List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
postProcessors.add(this);
AnnotationAwareOrderComparator.sort(postProcessors);
for (EnvironmentPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessEnvironment(event.getEnvironment(),
event.getSpringApplication());
}
}
List<EnvironmentPostProcessor> loadPostProcessors() {
return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class,
getClass().getClassLoader());
}
加载的所有EnvironmentPostProcessor列表如下:
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
org.springframework.cloud.client.HostInfoEnvironmentPostProcessor
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
org.springframework.boot.context.config.ConfigFileApplicationListener
org.springframework.cloud.netflix.metrics.ServoEnvironmentPostProcessor
org.springframework.cloud.sleuth.autoconfig.TraceEnvironmentPostProcessor
org.springframework.cloud.sleuth.autoconfig.TraceStreamEnvironmentPostProcessor
5、DelegatingApplicationListener
如果有通过配置context.listener.classes指定监听器,DelegatingApplicationListener会实例化这个监听器,让其处理事件。也就是说DelegatingApplicationListener会把处理逻辑委托给配置的监听器。
6、ClasspathLoggingApplicationListener
打印classpath地址
7、BootstrapApplicationListener
处理bootstrap.properties文件 ,生成父容器,逻辑有点复杂。
8、LoggingSystemShutdownListener、LoggingApplicationListener
预初始化日志系统(logback啥的)
contextPrepared
无
contextLoaded
容器启动后触发的事件,之后会涉及到
finished
1、LoggingApplicationListener
清理日志系统
EnvironmentPostProcessor处理
1、SpringApplicationJsonEnvironmentPostProcessor
解析json格式的系统变量,用处不大
2、HostInfoEnvironmentPostProcessor
读取机器和网络信息,添加环境变量spring.cloud.client.hostname和spring.cloud.client.ipAddress
3、ConfigFileApplicationListener
处理配置文件,较为复杂, 可暂时不管
4、TraceEnvironmentPostProcessor
给日志添加trace配置
5、TraceStreamEnvironmentPostProcessor
trace相关
ApplicationContextInitializer处理
1、SharedMetadataReaderFactoryContextInitializer
向容器中注册了CachingMetadataReaderFactoryPostProcessor,这是一个BeanDefinitionRegistryPostProcessor实现。
2、AutoConfigurationReportLoggingInitializer
向容器注册了AutoConfigurationReportListener
3、ConfigurationWarningsApplicationContextInitializer
向容器注册了ConfigurationWarningsPostProcessor,这是一个BeanDefinitionRegistryPostProcessor实现。
4、ContextIdApplicationContextInitializer
给容器设置ID
5、DelegatingApplicationContextInitializer
如果有配置context.initializer.classes,会实例化配置的类。委托给了配置的initializer。
6、ServerPortInfoApplicationContextInitializer
给容器注册了一个匿名的ApplicationListener,用于设置端口号











网友评论