//调用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 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 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
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()。
DefaultListableBeanFactory.classs的对象方法
registerSingleton(String beanName, Object singletonObject)->{
//DefaultSingletonBeanRegistry类对象方法
registerSingleton(beanName, singletonObject)->{
if(this.singletonObjects.get(beanName)==null){
//在singletonObjects添加对象
this.singletonObjects.put(beanName, singletonObject);
//其余移除或添加名字
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// 结构set(String),上面都是map结构
this.registeredSingletons.add(beanName);
}
}
//set结构
this.manualSingletonNames.add(beanName);
this.allBeanNamesByType.clear();
this.singletonBeanNamesByType.clear();
}
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)时,直接从一级缓存直接获取。



