Springboot启动过程
1.创建SpringApplication对象sp,初始化属性,例如资源加载器resourceLoader,启动类mainApplicationClass,webApplicationType类型,初始化器initializers和listeners(通过SpringFactoriesLoader类加载资源到cache)
2.调用sp.run(args)方法。
a.EventPublishingRunListener对象调用关于ApplicationStartingEvent对象的监听器。环境准备:其new StandardServletEnvironment对象,对该对象设置args,设置名为random(RandomValuePropertySource)资源。之后EventPublishingRunListener对象调用关于ApplicationEnvironmentPreparedEvent对象的监听器。其中一个ConfigFileApplicationListener作用加载random环境资源对象和OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.properties]'}资源对象以及加载EnvironmentPostProcessor的增强处理器,并调用。
b.new AnnotationConfigServletWebServerApplicationContext对象。属性AnnotatedBeanDefinitionReader(作用registerAnnotationConfigProcessors :在beanFactory,初始化ConfigurationClassPostProcessor在内的6个RootBeanDefinition对象)和ClassPathBeanDefinitionScanner。在该类的父类GenericApplicationContext无参构造方法中beanFactory = new DefaultListableBeanFactory()。有一个常用的注册单例方法beanFactory(String var1, Object var2)。初始化context的监听器和beanfactoryPostProcessors,最后EventPublishingRunListener 对象contextPrepared()。
c.beanFactory中的beanDefinitionMap中添加启动类BeanDefinition=AnnotatedGenericBeanDefinition,为Generic bean,其他为root bean。调用所有实现ApplicationContextAware接口的类的setApplicationContext(...)方法,接着EventPublishingRunListener对象调用关于ApplicationPreparedEvent事件对象的监听器。
d.context.refresh(),中从context中得到beanFactory,并初始化beanFactory。例如注册类加载器,加入BeanPostProcessor,初始化多播器SimpleApplicationEventMulticaster。在context.invokeBeanFactoryPostProcessors()方法中。ConfigurationClassPostProcessor对象.postProcessBeanDefinitionRegistry(registry)该方法中ConfigurationClassParser对象解析beanDefinitionMap中的启动类(AnnotatedGenericBeanDefinition)。扫描启动类的basePackages,ClassPathBeanDefinitionScanner/ConfigurationClassBeanDefinitionReader
类对象注册包中的类到beanDefinitionMap()。创建tomcatWebServer,之后发布上下文已经刷新事件,启动tomcat,发布servletwebserver已经被初始化事件。
e.context.publishEvent(ApplicationStartedEvent) 上下文对象发布应用启动完成事件。
f.调用ApplicationRunner和CommandLineRunner接口的实现类。context.publishEvent(ApplicationReadyEvent) 发布应用准备完成事件。
循环依赖
假设类a属性有b,b类属性有a。
1,创建a时,getBean(a)->doGetBean->doGetBean方法中:a.getSingleton(String beanName)判断(一级缓存singletonObjects取null && isSingletonCurrentlyInCreation(beanName))条件为false,返回null。b.getSingleton(String beanName, ObjectFactory<?> singletonFactory) 先a加入singletonsCurrentlyInCreation集合。调用doCreateBean(...)方法:先实例化a(未赋值),将a的name和得到a实例的lambda表达式放入三级缓存singletonFactories中并且清除a在二级缓存earlySingletonObjects的对象。之后populateBean()方法中,会解析a类的属性b,这时会getBean(b)。
2,创建b时,getBean(b)->doGetBean->doGetBean方法中:a.getSingleton(String beanName)判断(一级缓存singletonObjects取null && isSingletonCurrentlyInCreation(beanName))条件为false,返回null。b.getSingleton(String beanName, ObjectFactory<?> singletonFactory) 先b加入singletonsCurrentlyInCreation集合 ,后调用doCreateBean(...)方法:先实例化b(未赋值),将b的name和得到b实例的lambda表达式放入三级缓存singletonFactories中并且清除b在二级缓存earlySingletonObjects的对象。之后populateBean()方法中,会解析b类的属性a,这时会getBean(a)。
3.在getBean(a)->doGetBean->doGetBean方法中:a.getSingleton(String beanName)判断(一级缓存singletonObjects取null && isSingletonCurrentlyInCreation(beanName))条件为true,如果二级缓存为null,则从三级缓存获取。执行lambda表达式获取a的lambda表达从三级缓存移出到二级缓存。获取a实例赋值给b实例的a属性。
4. 将b移除singletonsCurrentlyInCreation集合,然后 b的实例加入一级缓存,b移除二和三级缓存。
5.将b实例赋值给a实例的属性b。将a移除singletonsCurrentlyInCreation集合,然后 a的实例加入一级缓存,a移除二和三级缓存。
6.getBean(b)时,直接从一级缓存直接获取。
//调用SpringApplication类的静态方法
ConfigurableApplicationContext run(Class<?> primarySource, String... args)
ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args){
//构造SpringApplication类对象,
//调用的SpringApplication的双参构造方法 SpringApplication(ResourceLoader resourceLoader,
// Class... primarySources)
return (new SpringApplication(primarySources)).run(args);
}
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
//初始化值sources,bannerMode,logStartupInfo,registerShutdownHook,resourceLoader
//additionalProfiles = new HashSet(),sources= new LinkedHashSet()
//primarysources 不能为空,为空即启动报错
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//使用枚举 public enum WebApplicationType {NONE,SERVLET,REACTIVE}
//如果有reactive.DispatcherHandler类则为WebApplicationType.REACTIVE
//如果有javax.servlet.Servlet和context.ConfigurableWebApplicationContext类则为
//WebApplicationType.SERVLET
this.webApplicationType = this.deduceWebApplicationType();
//1.在spring-boot:版本号.jar和spring-boot-autoconfigure:版本号.jar下
// METAINF下spring.factories下
// ApplicationContextInitializer组下的6个类,进行实例化,且对实现Order的接口进行排序
//2.SpringFactoriesLoader的静态方法loadFactoryNames方法及该方法内
// loadSpringFactories()读取spring.factores的所有内容到cache。然后
// ApplicationContextInitializer组的获取的6个类,
//3.排序后 1.DelegatingApplicationContextInitializer
// 2.ContextIdApplicationContextInitializer ...等等6个
this.setInitializers(this.getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//用上述同样的方法,获取METAINF下spring.factories下ApplicationContextInitializer组
//下的监听器,进行实例化,且对实现Order的接口进行排序
//第一个监听器类ConfigFileApplicationListener
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//得到启动main方法的类的class。
//通过new RuntimeException()对象,得到StackTraceElement[]对象中是main方法的
// StackTraceElement对象,通过StackTraceElement对象.getClassName()得到Class
this.mainApplicationClass = this.deduceMainApplicationClass();
}
public ConfigurableApplicationContext run(String... args) {
//StopWatch自带计时工具类。StopWatch.TaskInfo为内部类任务类其属性:
//taskName,任务名称。timeMillis 该任务耗时
//空参构造id=""
StopWatch stopWatch = new StopWatch();
//任务名称taskName=""。
//id="",taskName=""的耗时开始计时
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
//向系统System对象配置HeadLess属性
this.configureHeadlessProperty();
//SpringFactoriesLoader的cache中得到SpringApplicationRunListener组下的监听器
// 只有一个EventPublishingRunListener由两个重要属性
// SpringApplication application=springApplication对象
// SimpleApplicationEventMulticaster initialMulticaster对象
SpringApplicationRunListeners listeners = this.getRunListeners(args);
//通过调用initialMulticaster对象调用监听器的onApplicationEvent()
//下面是四个ApplicationStartEvent事件对象对应的监听器
//LoggingApplicationListener 初始化loggingSystem=LogbackLoggingSystem,
// 并且loggingSystem.beforeInitialize()->TurboFilterList表中添加FilterReply.DENY
//BackgroundPreinitializer 开启另为线程后台完成
// ConversionServiceInitializer(),ValidationInitializer()
// MessageConverterInitializer(),CharsetInitializer()等
//DelegatingApplicationListener doNothing
//LiquibaseServiceLocatorApplicationListener doNothing
listeners.starting();
Collection exceptionReporters;
try {
//封装args
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//1.根据webApplicationType=WebApplicationType.SERVLET创建
//StandardServletEnvironment对象,否则创建StandardEnvironment对象
//StandardServletEnvironment对象属性propertySource有
// servletConfigInitParams,servletContextInitParams,
// systemProperties,systemEnvironment,commandLineArgs,applicationConfig:
// [classpath:/application.properties]
//2.EventPublishingRunListener对象environmentPrepared(environment)方法
// 内部调用
//initialMulticaster.multicastEvent(ApplicationEnvironmentPreparedEvent)
// 对应ConfigFileApplicationListener,AnsiOutputApplicationListener
// LoggingApplicationListener,ClasspathLoggingApplicationListener
//BackgroundPreinitializer 等等
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
//向System对象设置spring.beaninfo.ignore=true
this.configureIgnoreBeanInfo(environment);
//如果bannerMode != Mode.OFF,则使用默认Banner为SpringBootBanner
Banner printedBanner = this.printBanner(environment);
//如果webApplicationType=SERVLET,则
// 利用Class.forName(web.servlet.context.AnnotationConfigServletWebServer
// ApplicationContext)空参构造创建对象,同时初始化this.refreshed=false
// 和this.beanFactory = new DefaultListableBeanFactory()和this.
// ignoreDependencyInterface=BeanNameAware/BeanFactoryAware/
// BeanClassLoaderAware.class等等
// 1.初始化this.reader = new AnnotatedBeanDefinitionReader(this);
// 初始化this.beanNameGenerator = new AnnotationBeanNameGenerator()
// 初始化this.scopeMetadataResolver = new
// AnnotationScopeMetadataResolver()
// 初始化this.registry = registry(BeanDefinitionRegistry);
// 初始化this.conditionEvaluator = new ConditionEvaluator(registry,
// environment, (ResourceLoader)null)
// AnnotationConfigUtils.registerAnnotationConfig
// Processors(this.registry)
// 设置DefaultListableBeanFactory beanFactory
// beanFactory.setDependencyComparator()
// beanFactory.setAutowireCandidateResolver
// beanFactory的beanDefinitionNames
// beanDefinitionMap,value为RootBeanDefinition分别为
// annotation.internalConfigurationAnnotationProcessor
// annotation.internalAutowiredAnnotationProcessor
// annotation.internalRequiredAnnotationProcessor
// annotation.internalCommonAnnotationPrecessor
// event.internalEventListenerProcessor
// event.internalEventListenerFactory
// 2.初始化this.scanner = new ClassPathBeanDefinitionScanner(this);
// this.beanDefinitionDefaults = new BeanDefinitionDefaults()
// this.beanNameGenerator = new AnnotationBeanNameGenerator()
// this.scopeMetadataResolver = new AnnotationScopeMetadataResolver()
// this.includeAnnotationConfig = true
// this.registry = registry;
// this.includeFilters=Component,javax.ManagedBean
// this.excludeFilters为0
// this.setEnvironment
// this.setResourceLoader
context = this.createApplicationContext();
//从缓存中加载SpringBootExceptionReporter组的类 ,封装成FailureAnalyzers
//类,其属性List<FailureAnalyzer> analyzers。
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
// 设置AnnotationConfigServletWebServerApplicationContext对象context
// context.setEnvironment(environment)
// SpringApplication对象.postProcessApplicationContext(context)
// beanNameGenerator与resourceLoader的设置
// SpringApplication对象.applyInitializers(context)
// 调用ApplicationContextInitializer接口的实现类的initialize()方法
// 例如ContextIdApplicationContextInitializer.initialize()方法
// 为applicationContext设置id=application和注册内部类ContextId
// 例如ServerPortInfoApplicationContextInitializer.initialize()
// 为applicationContext设置监听器ServerPortIn...ContextInitializer
// 例如SharedMetadataReaderFactoryContextInitializer.initialize
// 为applicationContext.addBeanFactoryPostProcessor
// CachingMetadataReaderFactoryPostProcessor对象
// listeners.contextPrepared(context)
// 使用EventPublishingRunListener.contextPrepared(context) nothing
// 打印启动相关日志和配置文件相关日志
// 向DefaultListableBeanFactory中sinletonObjects注册bean
// springApplicationArguments和springBootBanner
// Set<Object> sources = this.getAllSources();
// 将SpringApplication对象中的primarySources(启动类)
// 和sources,加入sources中
// this.load(context, sources.toArray(new Object[0]));
// 创建BeanDefinitionLoader loader对象,该对象属性
// 初始化sources=启动类.class
// 初始化annotatedReader=AnnotatedBeanDefinitionReader对象
// 初始化scanner=ClassPathBeanDefinitionScanner
// 向beanFactory中的beanDefinitionMap中添加启动类
// listeners.contextLoaded(context);
// 调用EventPublishingRunListener对象.contexted(context)方法
// 1.循环监听器,对某监听器实现ApplicationContextAware的接口
// 某监听器.setApplicationContext(context)
// 2.initialMulticaster.multicastEvent(ApplicationPreparedEvent)
// 对一些实现ApplicationListener接口的实现类调用
// listener.onApplicationEvent(event)
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
// this.refresh(context)
// context.refresh()->{
// ##context.prepareRefresh()->{
// 1 metadataReaderFactory属性metadataReaderCache清除
// 2 prepareRefresh()初始化startupDate,closed=false,active=ture
// 如果有ServletContex,ServletConfig,初始化PropertySources
// }
// ##beanFactory = this.obtainFreshBeanFactory()
// 初始化context.refreshed=ture,deflistBeanFac.serializationId
// ##this.prepareBeanFactory(beanFactory)
// 初始化beanClassLoader=AppClassLoader对象
// 初始化BeanPostProcessor=ApplicationContextAwareProcessor对象
// 初始化BeanPostProcessor=ApplicationListenerDetector对象
// 初始化BeanExpressionResolver=StandardBeanExpressionResolver对象
// 初始化PropertyEditorRegistrar=ResourceEditorRegistrar对象
// 初始化ignoreDependencyInterface=EnvironmentAware,
// EmbeddedValueResolverAware,ResourceLoaderAware,
// ApplicationEventPublisherAware,MessageSourceAware,
// ApplicationContextAware
// 初始化registerResolvableDependency=BeanFactory/ResourceLoader等
// beanFactory.registerSingleton(environment/systemProperties
// systemEnvironment)
// ##context.postProcessBeanFactory(beanFactory)
// beanFactory.addBeanPostProcessor(WebApplication
// ContextServletContextAwareProcessor)
// beanFactory.ignoreDependencyInterface(ServletContextAware.class)
// ##context.invokeBeanFactoryPostProcessors(beanFactory)
// 读取配置类,加载对象的beanDefinition到beanDefinitionMap
// invokeBeanFactoryPostProcessors有3个
// 1ConfigurationWarningsApplicationContextInitializer$Conf
// igurationWarningsPostProcessor
// 2SharedMetadataReaderFactoryContextInitializer$CachingMe
// tadataReaderFactoryPostProcessor
// 3ConfigFileApplicationListener$PropertySource
// OrderingPostProcessor
// regularPostProcessors放入3,
// registryProcessors放入1,2,ConfigurationClassPostProcessor后入
// processedBeans=internalConfigurationAnnotationProcessor
// currentRegistryProcessors=ConfigurationClassPostProcessor
// ConfigurationClassPostProcessor.processConfigBeanDefinitions
// (registry)
// 向List<BeanDefinitionHolder> configCandidate添加启动类
// BeanDefinitionHolder得到启动类的AnnotatedGenericBeanDefinition
// new ConfigurationClassParser.parse(configCandidate)
// new ConfigurationClassParser.processConfigurationClass(
// ConfigurationClass对象为启动类的相关信息)
// ConfigurationClassParser.doProcessConfigurationClass(
// 参数为启动类元数据)
// processMemberClasses(configClass,sourceClass)
// 处理sourceClass的内部类
// 处理PropertySources注解,处理ComponentScans注解
// 处理Import注解,
// 1,递归收集Import的类2,处理
// ,处理ImportResource注解,处理bean注解,处理方法
// 处理父类,子类
// ##this.registerBeanPostProcessors(beanFactory)
// PostProcessorRegistrationDelegate.registerBeanPostProcessors(...)
// priorityOrderedPostProcessors=2 AutowiredAnno
// tationBeanPostProcessor,3 RequiredAnnotat
// ionBeanPostProcessor
// ,1 CommonAnnotationBeanPostProcessor,
// 0 ConfigurationPropertiesBindingPostProcessor
// internalPostProcessors为priorityOrderedPostProcessor后3个
// orderedPostProcessor=MethodValidationPostProcessor
// nonOrderedPostProcessor=WebServerFactoryCusto
// mizerBeanPostProcessor,ErrorPageRegistrarBeanPostProcessor
// beanFactory添加priorityOrderedPostProcessors,
// orderedPostProcessor,nonOrderedPostProcessor,
// internalPostProcessors ,new ApplicationListenerDetector(...)
// ##this.initMessageSource()
// 用默认context.messageSource=new DelegatingMessageSource()
// 并向beanFactory注册该单例对象
// ##this.initApplicationEventMulticaster();
// 用默认context.applicationEventMulticaster=new
// SimpleApplicationEventMulticaster()
// 并向beanFactory注册该单例对象
// ##this.onRefresh();
// super.onRefresh()
// context.themeSource = new ResourceBundleThemeSource()
// context.createWebServer()->this.getWebServerFactory() 这个方法
// 会创建一些单例对象以及tomcatWebServer,
// beanFactory.doGetBean("tomcatServletWebServerFactory",...)
// beanFactory.getSingleton(...)
// 首先从this.singletonObjects取对象,为null且
// singletonsCurrentlyInCreation没有,则返回null。
// 在this.alreadyCreated没有创建,在mergedBeanDefinitions
// 清除object,在alreadyCreated加入object
// 根据名字从beanDefinitionMap得到ccbd,加入
// mergedBeanDefinitions
// ccbd单例,
// singletonsCurrentlyInCreation加入
// doCreateBean(...)
// createBeanInstance(...)
// instantiateBean() 调用无参构造器
// applyMergedBeanDefinitionPostProcessors
// 得到BeanPostProcessors,调用实现
// MergedBeanDefinitionPostProcessor接口,
// 调用postProcessMergedBeanDefinition()方法
// ccbd.postProcessed = true
//
// populateBean(...)
// InstantiationAwareBeanPostProcessor接口
// postProcessAfterInstantiation
// initializeBean(...)
// invokeAwareMethods()
// BeanNameAware/setBeanName(),
// BeanClassLoaderAware/setBeanClassLoader()
// BeanFactoryAware/setBeanFactory()
// applyBeanPostProcessorsBeforeInitialization()
// postProcessBeforeInitialization()
// invokeInitMethods()
// InitializingBean/afterPropertiesSet()
// invokeCustomInitMethod()
// applyBeanPostProcessorsAfterInitialization()
// postProcessAfterInitialization()
//
//
//
//
// 创建tomcatWebServer,在环境变量里添加servletContext=
// ApplicationContextFacade
//
// ##this.registerListeners();
// 初始化context.applicationEventMulticaster添加监听器及监听器bean
// ##this.finishBeanFactoryInitialization(beanFactory);
// beanFactory.configurationFrozen = true
// beanFactory.frozenBeanDefinitionNames=beanFactory
// .beanDefinitionNames
// beanFactory.preInstantiateSingletons(); 单例创建
// ##this.finishRefresh();
// context.publishEvent(ContextRefreshedEvent)
// context.webServer.start()
// context.publishEvent(ServletWebServerInitializedEvent)
// }
// context.registerShutdownHook()
// 如果SpringApplication对象的registerShutdownHook=ture,则向
// context注册shoutdown构造(在new线程中做context.doClose()->{
// ##context.publishEvent(ContextClosedEvent)
// ##context.destroyBeans()->{
// defaultListableBeanFactory.destroySingletons()
// 1.DefaultSingletonBeanRegistry.destroySingletons()
// 得到singletonObjects,
// 遍历disposableBeans的beanName
// De...SingleBeanRegistry.destroySingleton(beanName),
// def..List..BeanFactory.removeSingleton(beanName)
// singletonObjects.remove(beaname)
// singletonFactories.remove(beanName)
// earlySingletonObjects.remove(beanName)
// registeredSingletons.remove(beanName)
// factoryBeanObjectCache.remove(beanName)
// factoryBeanInstanceCache.remove(beanName)
// disposableBeans.remove(beanName)
// destroyBean(beanName,DisposableBeans)->{
// dependentBeanMap.remove(beanName)
// destroySingleton(dependentBeanName)
// }
// def..List.manualSingletonNames.remove(beanName);
// def..List.clearByTypeCache();
// containedBeanMap.clear()
// dependentBeanMap()
// dependenciesForBeanMap()
// clearSingletonCache()
//
// 2.defaultListableBeanFactory.manualSingletonNames.clear()
// 3.defaultListableBeanFactory.allBeanNamesByType.clear();
// default...beanFactory.singletonBeanNamesByType.clear();
// }
// ##context.closeBeanFactory()
// ##this.onClose();
// context.webServer.stop();TomcatWebServer
// ##this.active.set(false)
// })
this.afterRefresh(context, applicationArguments);
// doNothing
stopWatch.stop();
// 统计任务对象stopWatch.TaskInfo,属性taskName="" ,耗时timeMillis
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
// context.publishEvent(ApplicationStartedEvent) 上下文对象发布应用
// 启动完成事件
this.callRunners(context, applicationArguments);
// 调用ApplicationRunner和CommandLineRunner接口的实现类
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
// context.publishEvent(ApplicationReadyEvent) 发布应用准备完成事件
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}