首页>>后端>>Spring->springboot自动加载原理?

springboot自动加载原理?

时间:2023-12-05 本站 点击:0

Springboot 启动加载机制

Spring boot最大的好处就是遵从了java 约定大于配置 不用面对一大堆的配置文件,spring boot是根据你用的包来决定提供什么散孝滚配置。

springBoot的启动可以分为两个部分,第一部分:SpringApplication的实例化;第二部分:调用该实例运行run方法(springboot初始化)。

ApplicationContextInitializer:当springboot上慎段下文Context初始化完成后会调用

ApplicationListener:当springboot启动时事件change后都会触发

spring boot 初始化内容还是很多的,但是总结起来就四点:

即, 初始化BeanFactory,加载bean,启冲余动内置web容器;

发布ContextRefreshedEvent事件;

spring boot自动装配原理@EnableAutoConfiguration

1、spring boot启动会加载大量的自动配弯弊盯置类:(在下面的spring.factories文件中)

2、通过@ConditionalOnXXX判断我们是否导入了相关的功能(卜键就是pom文件中的starter),如果导入了,就会自动配置。

4、给容器中添加自动配置类的时候,埋和会从XXXProperties类中获取某些属性。我们只需要在配置文件中指定这些属性即可,如果没指定就会用默认值。

XXXA

比如:server.port

最后,通过配置:debug=true

可以查看失效和未生效的类(spring.factories文件中的)

SpringBoot运行原理

SpringBoot是一个基于Spring开发,集成了大量第三方库配置的javaweb开发框架

pom.xml

父依赖

其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件。以后我们导入依赖默认是不需要写版本的。

启动器spring-boot-starter

springboot-boot-starter-xxx:spring-boot的场景启动器郑御

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件。

springBoot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会被引进来,我们要用什么功能就导入什么样的场景启动器即可。

@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot运行这个类的main方法来启动SpringBoot应用。

进入这个注解,里面包含了很多其他注解

@ComponentScan作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中。

@SpringBootConfiguration作用:SpringBoot的配置类,标注在某个类上,表示这是一个姿咐SpringBoot的配置类。

进入@SpringBootConfiguration注解查看,这里的@Configuration说明这是一个配置类,配置类对应Spring的xml配置文件。

继续查看@SpringBootConfiguration包含的其他注解

@EnableAutoConfiguration:开启自动配置功能

进入@EnableAutoConfiguration注解查看

@AutoConfigurationPackage自动配置包

@import:Spring底层注解@import,给容器中导入一个组件

@Import({AutoConfigurationImportSelector.class})给容器导入组件

AutoConfigurationImportSelector:自动配置导入选择器。那么它导入哪些组件的选择器呢

这个类中有这样一个方法:getCandidateConfiguration,而在这个方法中有调用了SpringFactoriesLoader类的静态方法loadFactoryNames()方法

进入loadSpringFactories方法

根据全局搜索Spring.factories,打开后是自动配置的文件。

随便打开一个其中的自动配置类看,它们都喊册岩是javaConfig配置类,都注入了一些Bean

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中对应的org.springframework.boot.autoconfigure包下的配置项通过反射实例化为对应标注了@Configuration的javaConfig形式的IOC容器配置类,然后将这些都汇总成为一个实例并加载到IOC容器中。

结论:

1.SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值

2.将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作。

3.整个J2EE的整体解决方案和自动配置都在springboot-autoConfigure的jar包中。

4.它会给容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

5.有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。

SpringApplication

这个类主要做了以下四件事

1.推断应用的类型是普通的项目还是web项目

2.查找并加载所有可用初始化器,设置到initializers属性中

3.找出所有的应用程序监听器,设置到listeners属性中

4.推断并设置main方法的定义类,找到运行的主类

springboot加载自定义properties原理

springboot自定义属性文件通过value注解引入,和@autowired不同的是,它是由ConfigurationClassPostProcessor这个BeanDefinitionRegistryPostProcessor来处理,属性文件的读取和注入是在BeanDefinition级别,对象实例化之前。

我们建一个简单的类的梳理一下。

调用堆栈 从refresh开始,主要走了这几个方法:

invokeBeanFactoryPostProcessors

invokeBeanDefinitionRegistryPostProcessors

ConfigurationClassPostProcessor-processConfigBeanDefinitions

ConfigurationClassParser-doProcessConfigurationClass

ConfigurationClassParser-processPropertySource

ConfigurationClassParser-addPropertySource

ConfigurationClassParser主要方法:

doProcessConfigurationClass-processPropertySource-addPropertySource

逻辑主要集中在doProcessConfigurationClass方法圆带

doProcessConfigurationClass负责解析橘庆芦@PropertySource,@Import annotations,@ComponentScan等注解 。

1 调用processPropertySource处理自身差族的propertySource

2 扫描类上的ComponentScan,对扫出的类继续调用parse

3 处理@Import annotations等其他标签

processPropertySource结构很简单:

1根据注解里的location属性载入配置文件

2调用addPropertySource处理每个属性文件

addPropertySource这个类才是真正处理@value属性:

1把用户定义的properties文件加到Eniverment中去

2如果有相同name的属性文件,需要合并

CompositePropertySource 的场景其实是你有两个不同的文件,但是 @PropertySource中设置同样的name属性,这样CompositePropertySource 会做一个合并,按加入的时间顺序取。

增加一个product2,PropertySource name都设置为myprod

debug到addPropertySource,newSource和existing已经不一样了。

environment的propertySources里也有两份文件了。

面试官必问题:SpringBoot自动装配原理?!

首先会通过import导入DeferredImportSelector.

为什么要导入DeferredImportSelector呢,这是因为为了顺序州做的一个考虑,它的加载顺序是最后的,把它放到最后呢才能进行定制我们自己的,而不是以返迹前它的Bean优先

然后去扫描所有jar包中的spring.factories文件,把其中所有全类限定名封装成一个list,然后进行排序返回给Spring,然后Spring会漏清将它们注册是BeanDeifnition放到BeanDefinitionMap中去,然后Spring就能管理到这些Bean了


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Spring/12646.html