一步步吃透SpringBoot自动配置

在这里插入图片描述

🏆 作者简介:hh_hua,从0到1。
🏆《头衔》:CDSN优秀文章收藏者、CSDN从不评论者
🏆《近期荣誉》:妈妈说我是个好孩子
🏆《博客内容》:从nothing到everything
🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前置知识

🔎相关注解

🦋@ComponentScan

@ComponentScan:用于批量注册bean,该注解会让spring去扫描某些包及其子包中所有的类,然后将满足一定条件的类作为bean注册到spring容器容器中。(详见:@ComponentScan详解

🦋@Configuration

@Configuration:声明一个类为配置类,目的取代bean.xml配置文件注册bean对象。常与@Bean、@Scope、@Lazy搭配使用。(详解:@Configuration详解

配置类是什么?
使用注解和编程方式来代替传统的XML配置文件进行Spring框架配置的一种类,通过@Configuration来声明该类与普通类的区别,本质而言一种特殊的类。

为何存在配置类?
一切的目的都是为了简化开发,通过自动化的方式来提高生产效率,解放我们的双手。

🦋@Import

@Import:提供了一种显示地从其他地方加载配置类的方式,往往是从第三方导入配置类。(详解:@Import详解
三种导入方式

  • 普通类(相对于下面两种方式)
  • 接口ImportSelector的实现类
  • 接口ImportBeanDefinitionRegisrtar的实现类
    自动配置中使用了第二种方式

🔎SpringBoot启动过程

SpringBoot启动相当复杂,我们只谈重点,以简化之。
简版代码

SpringBoot启动流程的简化版代码:
public static void run(class<?> primaryClass) {
//1.创建一个ApplicationContext实例,即我们常说的IoC容器
ApplicationContext context = createApplicationContext();
//2.将主类(primaryClass)注册到IoC容器中〔简单但重要的第一步)
loadSourceclass(context, primaryclass);
//3.递归加载并处理所有的配置类
processConfigurationClasses(context)
/4.实例化所有的单例Bean(Singleton Bean)
instantiateSingletonBeans(context)
//5.如果是web应用,则启动web服务器(例如Tomcat)
startWebServer(context);

对应示图
在这里插入图片描述
详细讲讲重点步骤:加载并处理所有的配置类

加载并处理所有的配置类processConfigurationClasses(..)
public static void processConfigurationClasses(ApplicationContext context) {
//1.1首先从IoC容器中取出当前存在的源配置类
class<?> sourceConfigurationclass = getSourceConfigurationClass(context);
//2.创建一个配置类解析器,然后递归加载并处理应用中所有的配置类
ConfigClassParser parser = new ConfigClassParser(context);parser.parse(sourceConfigurationClass);
//3.1 向IoC容器中注册@Bean方法对应的BeanDefinition
loadBeanDefinitionsFromBeanNethods(parser.configurationClasses);
//3.2向IoC容器中注册ImportBeanDefinitionRegistrar导入的BeanDefinition
loadBeanDefinitionsFromRegistrars(parser.configurationClasses);

🚀什么是SpringBoot自动配置?

定义:SpringBoot 能够根据类路径中的jar依赖、定义的bean以及各种属性设置,自动配置应用的过程,从而使开发人员不在需要定义样板化的配置,按照约定进行编程。

自动配置与自动装配的区别
自动配置:Auto-Configuration,定义如上。
自动装配:Autowire是注解,用于依赖注入。

🚀SpringBoot是如何自动配置?

先放一张总图:
在这里插入图片描述

1.从主启动类的核心注解开始@SpringBootApplication
在这里插入图片描述
2.点进@SpringBootApplication,发现三个核心注解@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
在这里插入图片描述
3.先给结论:**@ComponentScan用于扫描指定的package,找到其中符合条件的类**。
@ComponentScan是用来扫描包,但是具体实现需要配合@EnableAutoConfiguration

具体实现:
根据@EnableAutoConfiguration注解中的@EnableAutoConfiguration注解。
在这里插入图片描述@EnableAutoConfiguration注解中有@Import({AutoConfigurationPackages.Registrar.class})一个注册器Registrar,通过这个注册器我们就可以找到当前类所在的包。
在这里插入图片描述

4.先给结论:@SpringBootConfiguration注解本质一个配置类,用于注册到Ioc容器中
在这里插入图片描述

5.先给结论:重中之重的注解@EnableAutoConfiguration用于读取到所有Jar包中的配置文件 META-IF/spring.factories 。

具体实现:
@EnableAutoConfiguration注解中有@Import({AutoConfigurationImportSelector.class}),自动配置导入选择器,即自动地、有选择地导入配置。
在这里插入图片描述
具体又是如何实现的呢?AutoConfigurationImportSelector实现了selectImports()方法,而这其中getAutoConfigurationEntry()方法。

 protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
			//1.获取 annotationNetadata 的注解@EnableAutoConfiguration 的属性
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
			//2.从资源文件 spring.factories中获取EnableAutoConfiguration对应的所有的类
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
			//3.通过在注解_@EnableAutoConfiguration 设置exclude 的相关属性,可以排除指定的自动配置类
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
			//4.根据注解@Conditional来判断是否需要排除某些自动配置类
            configurations = this.getConfigurationClassFilter().filter(configurations);
			//5.触发AutoConfiguration导入的相关事件
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationEntry(configurations, exclusions);
        }
    }

而这个getCandidateConfigurations方法的返回值是String,是真正帮我们去读到spring.factories配置文件 。
在这里插入图片描述
梳理:
1.通过@EnableAutoConfguration 里面的@AutoConfigurationPackage 注解,将主配置类的所在包皮下面所有子包里面的所有组件扫描加载到 Spring 容器中;
2.同时通过@EnableAutoConfguration 里面的 AutoConfigurationImportSelector 选择器中的 SringFactoriesLoader.loadFactoryNames()方法,获取类路径下的 META-INF/spring.factories 中的资源并经过一些列判断之后作为自动配置类生效到容器中,
3.自动配置类生效后帮我们进行自动配置工作,就会给容器中添加各种组件。

🚀SpringBoot如何修改配置?

虽然SpringBoot帮我们实现了自动配置,但是我们往往需要修改其默认值。对于每一个自动配置类(XXXAutoConfiguration),都对应着一个属性配置类(XXXAutoConfiguration)。前者实例化组件,后者在实例化组件过程中给某些属性赋值,而我们需要赋值的话,则需要通过修改application.xxx文件的方式。
例如:

//修改服务器端口号
server.port=8085
//修改日期格式
spring.mvc.format.date=yyyy-MM-dd

🚀总结

  • SpringBoot启动会加载大量的自动配置类。
  • 我们需要的功能有没有在SpringBoot默认写好的自动配置类当中,再来看这个自动配置类中到底配置了哪些组件,只要我们要用的组件在其中,我们就不需要再手动配置。
  • 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可。
    xxxxAutoConfigurartion:自动配置类;给容器中添加组件
    xxxxProperties:封装配置文件中相关属性;
  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值