3.SpringBoot篇-启动类源码简析.md

一、启动类分析 SpringApplication


1、构造函数初始化对象

构造四个对象,


	private ResourceLoader resourceLoader;
	//the primary bean sources 第一个主要的bean,入口类
	private Set<Class<?>> primarySources;
	//项目类型,默认servlet
	private WebApplicationType webApplicationType;
	
	private Class<?> mainApplicationClass;

  • 1.1、设置ApplicationContextInitializer初始化这种类型的bean,主要通过(META-INF/spring.factories)声明的类

  • 1.2、获取类型bean主要通过SpringApplication.getSpringFactoriesInstances这个方法获得
    #这个方法会加载了各种配置,读取jar包下面的META-INF/spring.factories文件中声明的类名,
    META-INF/spring.factories声明各种类

  • 1.3、生成获取需要的Instrance,SpringApplication.createSpringFactoriesInstances

  • 1.4、主要做了,获取入口main函数的类,


总结:META-INF/spring.factories文件中声明的类名,初始化了1.ApplicationContextInitializer和2.ApplicationListener两种,确定项目类型(web,还是其他),Sources类,就是注解了@SpringApplication的类


2、启动类run方法

	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			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);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
  • 启动监听器SpringApplicationRunListeners,监听spring的启动的功能,spring启动的生命周期,

  • 2.1 搞一个生命周期的stopWatch

  • 2.2 初始化SpringApplicationRunListener监听器,监听spring的周期

  • 2.3 ApplicationArguments处理java的arg参数,读取–spring=的启动参数

  • 2.4 初始化ConfigurableEnvironment,初始化变量,拿ApplicationArguments进行处理,先拿到最出类型的StandardServletEnvironment,这个类是储存配置的和环境变量等变量

#配置类-添加PropertySource,这个是用来获取配置的
#web类型的初始化配置StandardServletEnvironment会加入以下的property变量
StandardServletEnvironmentPropertySource
StubPropertySource 用于占位
MapPropertySource                       系统变量
SystemEnvironmentPropertySource         系统环境变量

#然后配置文件加入到environment中
configurePropertySources(environment, args);//加入命令行source,CompositePropertySource
configureProfiles(environment, args);

#将environment和SpringApplication类绑定在一起
使用Binder类绑定
这个类需要了解再去了解吧,Binder类,Binder类,Binder类,Binder类还不清楚怎么用

  • 2.5 彩蛋打印banner 找classPath下的banner文件,可打印图片
  • 2.6 生成createApplicationContext 生成spring上下文
#web使用, application context作文上下文
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext

初始的AnnotationConfigServletWebServerApplicationContext的过程
1、这个类主要生成两个,注册器
AnnotatedBeanDefinitionReader   注解定义
ClassPathBeanDefinitionScanner  classPath定义 
 

AnnotatedBeanDefinitionReader

#用于处理注解的类,将environment环境配置数据做处理,查找各种注解并且处理

1、获取初始的AnnotationConfigServletWebServerApplicationContext(注册机)的DefaultListableBeanFactory
设置注解bean依赖的排序处理器,AnnotationAwareOrderComparator
添加ContextAnnotationAutowireCandidateResolver,Autowire condidate解决Lazy懒加载的处理

注册这些BeanDefinition
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
org.springframework.context.annotation.internalPersistenceAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory

ClassPathBeanDefinitionScanner

#用户处理classPath的scanner扫描

  • 2.7 处理spring启动异常处理器,初始化
    #处理spring启动报错的异常
    #META-INF/spring.factories下实现了SpringBootExceptionReporter这里的类
			exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);

  • 2.8 准备问上下文
#run入口中有
一、			
prepareContext(context, environment, listeners, applicationArguments, printedBanner);  

二、prepareContext处理(提前准备一些springboot的配置类)
1、给context设置environment
2postProcessApplicationContext(context);//设置ResourceLoader
3、applyInitializers,执行ApplicationContextInitializer,开放功能,执行init
4、listeners.contextPrepared(context);开放功能执行contextPrepared
5、注册两个bean,springApplicationArguments,springBootBanner//banner,jvm参数处理等
5BeanDefinitionLoader加载数据,注册资源上的数据,资源类型有注解类,xml,classPath、这一步是主要的bean容器初始化。
//注册一些bean的信息由该doRegisterBean方法触发功能
{
    5.1. 注册某些bean的定义  
}
6、listeners.contextLoaded(context);推送监听器时间


三、refreshContext,开始初始化bean容器,(spring初始化的过程)
1、方法大概功能
主要的入口是AbstractApplicationContextrefresh() 方法
1.1 准备上下文的刷新的一些信息,PropertySources配置等
1.2 获取beanFactory工厂
1.3 beanFactory工厂使用当前上下文context
2、 invokeBeanFactoryPostProcessors,bean工厂的后置处理器
------BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
------所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
这里两种Bean定义后处理器
BeanDefinitionRegistryPostProcessor是在BeanFactoryPostProcessor的前面执行。

springboot会使用ConfigurationClassPostProcessor这个bean后处理器去扫描bean,注册bean这个类就是继承了BeanDefinitionRegistryPostProcessor,加载一些配置类


2.1 重点springboot,配置bean注册后处理器,ConfigurationClassPostProcessor
2.2 解析处理,ConfigurationClassParser的parse方法
ClassPathBeanDefinitionScanner扫描,处理bean上面的注解,
useDefaultFilters,nameGenerator,scopedProxy,scopeResolver,resourcePattern,includeFilters,excludeFilters,lazyInit,basePackages,basePackageClasses,
等等属性,
最后doScan扫描一波包
scanner.doScan(StringUtils.toStringArray(basePackages));
把数据都注册到注册器的beanDefinition里面

2.3 到这一步,就已经把所有的beanDefinition定义已经都初始化好了 

四、注册国际化语言MessageSource
五、注册initApplicationEventMulticaster时间监听bean,初始化时间委派器
六、onRefresh()准备好createWebServer,初始化TomcatServletWebServerFactory
tomcat工厂,然后初始化配置文件initPropertySources,
六、 Check for listener beans and register them.注册监听的bean到,初始化时间委派器中,:默认用:SimpleApplicationEventMulticaster
七、初始化所有非懒加载的bean,finishBeanFactoryInitialization
八、然后启动tomcat,推送各种事件,容器启动事件,tomcat启动事件,上下文启动事件,
九、执行callRunners,执行命令行等,
十、推送各种-spring运行时间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值