springboot启动过程思维导图
2022-01-27 15:09:42 0 举报
AI智能生成
登录查看完整内容
介绍了springboot启动的详细过程
作者其他创作
大纲/内容
通过判断classpath下是否有servlet或者react的相关类来决定容器类型
判断容器类型this.webApplicationType = deduceWebApplicationType();
读取META-INF/spring.factories
存入cache
SpringFactoriesLoader类,用于加载META-INF/spring.factories配置中的类持有一个cache静态变量
getSpringFactoriesInstances(ApplicationContextInitializer.class)
实例化
setInitializers(被实例化的类的列表);//设置this.initializers
设置this.initializerssetInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));获取ApplicationContextInitializer类型的配置类,存储在this.initializers中
直接从SpringFactoriesLoader的cache中获取
getSpringFactoriesInstances(ApplicationListener.class)
setListeners(被实例化的类的列表);//设置this.listeners
设置this.listenerssetListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
通过抛出一个异常,然后在异常堆栈中找到包含main方法的类
设置this.mainApplicationClass
SpringApplication的构造方法
getSpringFactoriesInstances(SpringApplicationRunListener.class)
EventPublishingRunListener持有2个成员变量application和initialMulticaster
this.application = application;
持有几个成员变量如下:
ListenerRetriever持有3个成员变量如下,构造器中初始化它们
public final Set<ApplicationListener<?>> applicationListeners;
public final Set<String> applicationListenerBeans;
private final boolean preFiltered;
private final ListenerRetriever defaultRetriever=new ListenerRetriever(false);
其他待补充
this.initialMulticaster = new SimpleApplicationEventMulticaster();
this.defaultRetriever.applicationListeners.add(listener);
获取容器所有的ApplicationListener:application.getListeners(),然后放入initialMulticaster的defaultRetriever中this.initialMulticaster.addApplicationListener(listener);
实例化EventPublishingRunListener
实例化,默认只有一个类被实例化EventPublishingRunListener
SpringApplicationRunListeners持有一个this.listeners变量,在其构造方法中给该变量赋值
private final List<SpringApplicationRunListener> listeners;
默认只有一个元素:SimpleApplicationEventMulticaster的实例
this.listeners = new ArrayList<>(SpringApplicationRunListener列表);
new SpringApplicationRunListeners(被实例化的类的列表)
创建一个SpringApplicationRunListeners对象SpringApplicationRunListeners listeners = getRunListeners(args);
普通springboot项目包含4个支持ApplicationStartingEvent类型的listener,如下
onApplicationStartingEvent((ApplicationStartingEvent) event);在这里指定日志系统,如果没有指定,则根据LoggingSystem.SYSTEMS中指定的第一个作为日志系统(即logback)
LoggingApplicationListener
另起一个线程进行预初始化(用处好像不大,预初始化的类也没有注入容器中)
BackgroundPreinitializer
什么也不做
DelegatingApplicationListener
LiquibaseServiceLocatorApplicationListener
listener.onApplicationEvent(event);
SimpleApplicationEventMulticaster的multicastEvent方法
默认情况下只有一个SpringApplicationRunListener实例,即EventPublishingRunListener实例调用该实例的starting方法
启动监听listeners.starting();
类继承关系如下StandardServletEnvironment,无显式构造方法StandardEnvironment,无显式构造方法AbstractEnvironment,有显式构造方法StandardServletEnvironment实例化的时候,调用AbstractEnvironment构造方法,在该构造方法中调用了customizePropertySources(this.propertySources);因此会执行孙类的customizePropertySources方法,孙类通过super调用子类的customizePropertySources方法。完成初始化。创建的该environment只是一个空壳无实际有用内容。
new StandardServletEnvironment();
创建environmentenvironment = getOrCreateEnvironment();
默认什么都不做;如果有命令行参数则向environment的MutablePropertySources变量增加一个SimpleCommandLinePropertySource实例
默认什么都不做;
配置environmentconfigureEnvironment(environment);
普通的springboot项目会调用如下ApplicationListener
对springboot
对springcloud
从spring.factories获取EnvironmentPostProcessor类型,并实例化,返回实例列表List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
对于springboot默认由如下processor
SystemEnvironmentPropertySourceEnvironmentPostProcessor
SpringApplicationJsonEnvironmentPostProcessor
会进行如下两步:
RandomValuePropertySource.addToEnvironment(environment);
创建Loader对象
还没读懂,待完善
load方法
ConfigFileApplicationListener也就是调用者自身也是一个postProcessor
遍历返回的EnvironmentPostProcessor类型实例的列表并调用postProcessor.postProcessEnvironment(environment)
ConfigFileApplicationListener
不重要,如果电脑支持ANSI字符格式,输出日志添加彩色显示。
AnsiOutputApplicationListener
初始化日志系统,包括设定日志级别等等。内容挺多,后面如果有需要再探究其源码
ClasspathLoggingApplicationListener
如果配置文件中配置了context.listener.classes,则实例化该类并且放入SimpleApplicationEventMulticaster对象所持有的this.defaultRetriever.applicationListeners中
不重要
FileEncodingApplicationListener
SimpleApplicationEventMulticaster.multicastEvent()
EventPublishingRunListener.environmentPrepared()
listeners.environmentPrepared(environment);
准备环境ConfigurableEnvironment environment = prepareEnvironment(listeners);
该类的继承关系如下
该方法注册如下bean到beanFactory中
internalConfigurationAnnotationProcessor
internalAutowiredAnnotationProcessor
internalRequiredAnnotationProcessor
internalCommonAnnotationProcessor
internalEventListenerProcessor
internalEventListenerFactory
构造器中调用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
this.reader = new AnnotatedBeanDefinitionReader(this);
构造器中做如下三件事
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
this.includeFilters.add(new AnnotationTypeFilter(ManagedBean.class));
this.includeFilters.add(new AnnotationTypeFilter(Named.class));
注册默认Filter:registerDefaultFilters();
this.environment = environment;
setResourceLoader(resourceLoader);
this.scanner = new ClassPathBeanDefinitionScanner(this);
AnnotationConfigServletWebServerApplicationContext
ServletWebServerApplicationContext
GenericWebApplicationContext
this.beanFactory = new DefaultListableBeanFactory();
GenericApplicationContext
this.resourcePatternResolver = getResourcePatternResolver();
AbstractApplicationContext
this.classLoader = ClassUtils.getDefaultClassLoader();
DefaultResourceLoader
实例化AnnotationConfigServletWebServerApplicationContext
创建容器context = createApplicationContext();
context类型为AnnotationConfigServletWebServerApplicationContext,在实例化的时候默认持有一个environment,但是该environment的propertySourceList为4个默认的元素,这里使用在SpringApplication中创建的environment代替,propertySourceList有9个元素。
context.setEnvironment(environment);
默认情况下什么都不做
postProcessApplicationContext(context);
对于springboot默认有如下initializer的initialize方法被执行
获取配置文件配置的context.initializer.classes,用逗号分割,得到一个list
遍历这个list,执行这些initializer的initialize方法
DelegatingApplicationContextInitializer
实例化ContextIdApplicationContextInitializer$ContextId并放入beanFactory的registeredSingletons中
ContextIdApplicationContextInitializer
创建一个postProcessor:new ConfigurationWarningsPostProcessor(getChecks())
把这个postProcessor放入context的this.beanFactoryPostProcessors中:context.addBeanFactoryPostProcessor(创建的postProcessor);
ConfigurationWarningsApplicationContextInitializer
把当前对象放入applicationContext的this.applicationListeners中:applicationContext.addApplicationListener(this);
ServerPortInfoApplicationContextInitializer
创建一个postProcessor:new CachingMetadataReaderFactoryPostProcessor()
SharedMetadataReaderFactoryContextInitializer
创建一个applicationListener:new ConditionEvaluationReportListener()
把这个applicationListener放入context的this.applicationListeners中:applicationContext.addApplicationListener(创建的applicationListener);
ConditionEvaluationReportLoggingListener
applyInitializers(context);
SpringApplicationRunListeners对象的listeners只有一个元素,即EventPublishingRunListener实例,该实例的contextPrepared方法是空的,什么也不做。
此处还是在SpringApplication类中,listeners是SpringApplicationRunListeners对象
listeners.contextPrepared(context);
把applicationArguments放入beanFactory的registeredSingletons列表中
context.getBeanFactory().registerSingleton(\"springApplicationArguments\
子主题
该实例包含如下属性:
this.registry = 当前context对象;
this.beanNameGenerator = new AnnotationBeanNameGenerator();用于生成beanname
在创建context时已经注册过了,这里其实什么也不做,需要注册的postProcessor如下:
注册默认的postProcessorAnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
创建xmlReader:this.xmlReader = new XmlBeanDefinitionReader(registry);
context创建时我们已经见过这个scanner的创建过程,在这里loader也创建一个并作为loader的成员变量
和context中的scanner区别:this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));作用?
this.scanner = new ClassPathBeanDefinitionScanner(registry);
loader持有一个this.sources,根据source类型分别调用不同的load方法,如下:
创建BeanDefinition实例:AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
处理Common注解,包括以下几种:是否含有@Lazy注解---abd设置this.lazyInit是否有@Primary注解---abd设置this.primary是否有@DependsOn注解---abd设置this.dependsOn是否有@Role注解---abd设置this.role是否有@Description注解---abd设置this.description
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
如果是DEFAULT或者NO,则直接返回该definitionHolder
如果是后两种,则新创建一个definitionHolder返回。使用代理
this.annotatedReader.register(source);
springboot默认类型:source instanceof Class<?>
source instanceof Resource
source instanceof Package
source instanceof CharSequence
loader.load();
这里的listeners是SpringApplicationRunListeners对象,调用了EventPublishingRunListener对象的contextLoaded方法
在EventPublishingRunListener中做如下几件事:
1、在SpringApplication中获取所有的ApplicationListener
2、遍历这些listeners2.1 context添加ApplicationListener:context.addApplicationListener(listener);2.2 如果listener instanceof ApplicationContextAware则((ApplicationContextAware) listener).setApplicationContext(context);
SimpleApplicationEventMulticaster的multicastEvent方法做如下几件事
该对象已经缓存了ApplicationListener列表,在this.defaultRetriever.applicationListeners中,是该对象实例化时在SpringApplication的listeners获取的
遍历this.defaultRetriever.applicationListeners,判断是否支持ApplicationPreparedEvent事件类型,返回符合条件的实例列表
调用的listener有如下几个:
context中新增了一个postProcessor:new PropertySourceOrderingPostProcessor(context)
listeners.contextLoaded(context);
获取environmentConfigurableEnvironment env = getEnvironment();
getPropertySources()返回environment持有的this.propertySources实例
initPropertySources();
prepareRefresh();
得到beanFactory:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));这里创建一个StandardBeanExpressionResolver实例,并设置到beanFactory的this.beanExpressionResolver属性用于解析spel表达式
添加一个postProcessorbeanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
向beanFactory的this.ignoredDependencyInterfaces添加接口,有什么用?后续补充,添加的接口有如下几个:EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware
向beanFactory的this.resolvableDependencies添加接口,有什么用?后续补充,添加的接口有如下几个:BeanFactoryResourceLoaderApplicationEventPublisherApplicationContext
添加一个postProcessorbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
beanFactory.containsLocalBean方法,只在当前beanFactory中查找,不查找parentBeanFactory
prepareBeanFactory(beanFactory);
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(ServletContextAware.class);
postProcessBeanFactory(beanFactory);
获取context的postProcessor列表:getBeanFactoryPostProcessors()
定义两个list,分别存放两种不同的postProcessorList<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
postProcessBeanDefinitionRegistry方法什么也不做
ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor
注册internalCachingMetadataReaderFactory
为beanFactory中注册的internalConfigurationAnnotationProcessor的BeanDefinition添加ropertyValue---internalCachingMetadataReaderFactory
postProcessBeanDefinitionRegistry方法
SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor
是regularPostProcessor
ConfigFileApplicationListener$PropertySourceOrderingPostProcessor
遍历beanFactoryPostProcessors1、如果是BeanDefinitionRegistryPostProcessor类型,则:registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);2、如果不是BeanDefinitionRegistryPostProcessor类型,则:regularPostProcessors.add(postProcessor);
经过上面一步,regularPostProcessors含有1个元素:ConfigFileApplicationListener$PropertySourceOrderingPostProcessorregistryProcessors含有两个元素:[ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor,SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor]this.beanDefinitionMap新增了3个实例
currentRegistryProcessors只有一个元素,是上一步获取到的ConfigurationClassPostProcessor
获取到所有注册的bean列表
最后我们获取到的配置类往往只有一个:App.class
实例化注解扫描器this.componentScanParser = new ComponentScanAnnotationParser
实例化配置类解析器ConfigurationClassParser parser = new ConfigurationClassParser()
是否有@PropertySource注解,并处理该注解
处理@ComponentScan注解,会递归查找子注解
处理@ImportResource注解
处理@Bean methods
处理父类
如果sourceClass非空,说明有父类,继续处理父类
这个方法比较复杂,一时难以读懂,有一步比较重要,返回spring.factories中配置的EnableAutoConfiguration类,并注册到beanFactory,如下:
List<String> configurations = getCandidateConfigurations();
String[] imports = deferredImportSelector.selectImports(annotationMetadata);
DeferredImportSelectorGrouping持有个this.group实例,该实例调用this.group.process()方法
grouping.getImports()
processDeferredImportSelectors();
解析配置类parser.parse(configCandidates);
注册上一步获取到的configClasses,注册到beanFactory。细节待补充
this.reader.loadBeanDefinitions(configClasses);
processConfigBeanDefinitions(registry);
ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
遍历currentRegistryProcessors,调用postProcessor.postProcessBeanDefinitionRegistry(registry);
首先处理实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
步骤和上面一样
把符合条件的postProcessor添加到registryProcessors,此时,registryProcessors含有4个元素:[ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor,SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor,ConfigurationClassPostProcessor,RefreshScope]
然后处理实现了Ordered接口的BeanDefinitionRegistryPostProcessor
把符合条件的postProcessor添加到registryProcessors
最后处理[实现了PriorityOrdered接口和Ordered接口]之外的BeanDefinitionRegistryPostProcessor
调用的配置类有如下几种
空方法
ConfigurationWarningsApplicationContextInitializer的postProcessBeanFactory方法
SharedMetadataReaderFactoryContextInitializer的postProcessBeanFactory方法
获取所有注册的bean
遍历所有注册的bean,判断是否是FullConfiguration,得到所有的FullConfiguration列表
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
enhanceConfigurationClasses(beanFactory);
新增一个postProcessorbeanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
ConfigurationClassPostProcessor的postProcessBeanFactory方法
ConfigFileApplicationListener的postProcessBeanFactory方法
从所有已注册的bean中获取到beanPostProcessor列表
遍历该列表,区分三种情况,分别放入如下list中priorityOrderedPostProcessorsorderedPostProcessorNamesnonOrderedPostProcessorNames
调用的processor有如下几种
方法较复杂,待后续补充可参考:https://www.jianshu.com/p/420899939449下面解析过程是根据该文档总结的
PropertySourcesPlaceholderConfigurer持有一个this.propertySources列表分别是:environmentProperties和localProperties,分别表示servlet环境属性和本地属性
获取到所有已注册bean的列表
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
这是核心方法,在这里处理占位符替换事宜,将占位符替换为属性文件中的值
遍历这个列表,依次处理visitor.visitBeanDefinition(bd);
PropertySourcesPlaceholderConfigurer的postProcessBeanFactory方法
列表为空
ConfigurationBeanFactoryMetadata的postProcessBeanFactory方法
ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor的postProcessBeanFactory方法
上面第二步:遍历beanFactoryPostProcessors1、如果是BeanDefinitionRegistryPostProcessor类型,则:registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);2、如果不是BeanDefinitionRegistryPostProcessor类型,则:regularPostProcessors.add(postProcessor);上面步骤中已经把beanPostProcessor都注册到beanFactory中,而且过程中有新增的beanPostProcessor这里从所有已注册的bean中获取beanPostProcessor,得到一个列表
invokeBeanFactoryPostProcessors(beanFactory);
beanFactory中获取注册的BeanPostProcessor类型的bean列表遍历该列表,区分三种情况,分别放入如下list中priorityOrderedPostProcessorsorderedPostProcessorNamesnonOrderedPostProcessorNames
遍历该列表,向beanFactory中添加BeanPostProcessorbeanFactory.addBeanPostProcessor(postProcessor);
首先处理实现了PriorityOrdered接口的BeanPostProcessor
步骤相同
其次处理实现了Ordered接口的BeanPostProcessor
最后处理其他BeanPostProcessor
registerBeanPostProcessors(beanFactory);
initApplicationEventMulticaster();
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
super.onRefresh();
从beanFactory获取注册的ServletWebServerFactory并实例化TomcatServletWebServerFactory
getSelfInitializer()返回一个方法,但是并不执行,请注意return this::selfInitialize;//jdk8新特性
Tomcat tomcat = new Tomcat();
创建临时目录File baseDir =createTempDir(\"tomcat\")
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);//this.protocol=org.apache.coyote.http11.Http11NioProtocol
server = new StandardServer();
server.setCatalinaBase(baseFile);server.setCatalinaHome(baseFile);
Service service = new StandardService();
server.addService(service);
创建Server
server.service.addConnector(connector);
connector.setPort(port);
设置ssl等其他一些设置
customizeConnector(connector);
启动tomcatthis.tomcat.start();
initialize();
返回 getTomcatWebServer(tomcat);
TomcatServletWebServerFactory的getWebServer()方法,实例化并启动tomcat容器
调用factory.getWebServer返回一个WebServer实例this.webServer = factory.getWebServer(getSelfInitializer());
ServletWebServerFactory factory = getWebServerFactory();
createWebServer();
onrefresh方法主要工作是初始化tomcat容器,和tomcat容器相关的bean也会实例化。我们可以看到该函数执行完毕后,实例化列表实例数目骤增。
onRefresh();
获取context的ApplicationListener列表,添加到context的applicationEventMulticaster中applicationEventMulticaster.defaultRetriever.applicationListeners.add(listener);
从beanFactory已注册的bean中获取ApplicationListener类型的列表,添加到context的applicationEventMulticaster中this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
registerListeners();
冻结所有bean定义,不会再有修改beanFactory.freezeConfiguration();
实例化所有beanbeanFactory.preInstantiateSingletons();
finishBeanFactoryInitialization(beanFactory);
启动web容器WebServer webServer = startWebServer();
finishRefresh();
调用springframework的refresh()方法
refreshContext(context);
afterRefresh(context);
run(String... args)
new SpringApplication(primarySources).run(args);
收藏
0 条评论
回复 删除
下一页