SpringBoot
2021-04-18 20:18:08 0 举报
AI智能生成
登录查看完整内容
SpingBoot在启动时候坐了哪些事情:两条路:注解和Run方法
作者其他创作
大纲/内容
SpringBoot启动分析
线路一:@SpringBootApplication
@SpringBootConfiguration 配置类
@Configurationpublic @interface SpringBootConfiguration{}
SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类
@EnableAutoConfiguration 开启自动配置功能
@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {
@AutoConfigurationPackage 作用是将添加该注解的类所在的packpage作为自动配置进行管理(要扫描哪些包)
@Import(AutoConfigurationPackages.Registrar.class)public @interface AutoConfigurationPackage {}
Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
@Import(AutoConfigurationPackages.Registrar.class) 自动配置导入选择器
AutoConfigurationImportSelector自动配置导入选择器,那么它会导入哪些组件的选择器呢?
点进去看会发现有这样一个方法
public String[] selectImports(AnnotationMetadata annotationMetadata) {}
99:getAutoConfigurationEntry //获取自动配置类
123:getCandidateConfigurations //获取候选配置
假如没有断言呢?继续向下跟踪
loadFactoryNames方法(使用给定的类加载器从“ META-INF / spring.factories”加载给定类型的工厂实现的标准类名)
loadSpringFactories
OK,我们现在知道SpringBoot的自动配置是哪里来的了,下面我们返回Run方法,请回到开头←
@ComponentScan自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中
路线二:Run方法追踪
这里可以总结为两步
1、一直深入不是run方法为止
public ConfigurableApplicationContext run(String... args)
printBanner(environment);
createApplicationContext();
refreshContext(context);
refresh((ApplicationContext) context);
refreshContext(context)
applicationContext.refresh();
super.refresh();
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
继续跟进方法:invokeBeanFactoryPostProcessors
postProcessBeanDefinitionRegistry
processConfigBeanDefinitions(registry);
331:parser.parse(candidates);//解析候选配置
processConfigurationClass
递归处理配置类及其超类层次结构
点进去这个类你会发现注解的处理是在这里进行的
我们现在只关心线路一中的public String[] selectImports(AnnotationMetadata annotationMetadata) {}是哪里调用的
我们知道,在主启动类上的import注解里面会加载配置类,那么谁来调用加载呢?
找到310行,对于@Import注解的处理
581:String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
是不是又回到了最初的起点?
registerBeanPostProcessors(beanFactory);
registerListeners();
2、通过构造方法加载初始化
WebApplicationType.deduceFromClasspath();
判断了我们的工程到底是个什么类型(web工程,基本的spring工程等)
getSpringFactoriesInstances(ApplicationContextInitializer.class));
loadSpringFactories(classLoaderToUse)
通过类加载器获取META-INF/spring.factories文件生成并返回实例工厂
Pom文件
为什么有些启动器和依赖不用写版本号?
点进去看看
再点进去看看,你会发现,里面存有大量的版本管理
收藏
0 条评论
回复 删除
下一页