SpringBoot自动配置原理分析

首先,我们要明确一点的是,SpringBoot不是一个代替Spring的新框架,它的目的是用来简化Spring应用开发的。
Spring的目的是简化Java开发,SpringBoot的目的是简化Spring开发。
先来看看SpringBoot的使用,下面是SpringBoot的典型使用:

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

上面代码和普通启动类的区别有两处:类上的注解 @SpringBootApplication 和 main方法中的SpringApplication.run方法调用。我们就来分析一下这两个地方。

@SpringBootApplication

直接看这个注解,看不出什么东西。进到它的定义去看,它是一个组合注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication { 
... 
}

其中,@Target、@Retention、@Documented、@Inherited都是一些元注解,重要的是@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 这三个注解。

1. @SpringBootConfiguration

进到 @SpringBootConfiguration 的定义,

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration{
...
}

它里面就是一个@Configuration。我们知道这个注解是用来使用JavaConfig形式配置Spring容器中的Bean。这是SpringBoot推荐使用的Bean配置形式。所以我们在使用SpringBoot的时候,没有任何的xml配置文件。

2. @ComponentScan

这个注解是Spring里面的自动扫描和装配Bean的注解。它里面使用了 excludeFilters 属性,这个属性指定了哪些类不需要被装配。type = FilterType.CUSTOM 表示自定义FilterClass排除。
@ComponentScan默认扫描的是本包以及子包下面的所有类,所以SpringBoot项目的包结构通常像下面这样
在这里插入图片描述
启动类放在根package下面。也可以通过basePackages属性来指定要扫描的路径。

3. @EnableAutoConfiguration

这个注解就是SpringBoot自动配置原理的核心注解,也是一个组合注解。看到这个注解以Enable开头,会不会想到Spring里面的@EnableScheduling、@EnableCaching等以Enable开头的注解?作用都是开启某项功能的使用,原理都是借助@Import的支持,收集和注册特定场景相关的bean定义。
来看它的定义

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}

果然有一个@Import注解。 里面的@AutoConfigurationPackage 这个注解实现的是一个自动扫描功能。
@Import(AutoConfigurationImportSelector.class),从名称来看,它导入了一个自动配置导入选择器。我们进入AutoConfigurationImportSelector这个类看看源码,里面实现了selectImports方法
在这里插入图片描述
继续点进getAutoConfigurationEntry方法中,这个方法按照意思是获取默认配置入口
在这里插入图片描述
继续进入getCandidateConfigurations方法,这个方法的意思是获取候选配置
在这里插入图片描述
里面的 SpringFactoriesLoader.loadFactoryNames()方法是真正的加载配置的地方。
在这里插入图片描述
它其实是去加载一个外部的文件,而这个文件是在jar包里面的 META-INF/spring.factories 这个路径中,
在这里插入图片描述
SpringFactoriesLoader配合@EnableAutoConfiguration注解使用,根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应的一组@Configuration类,配置项也是全类名,可以通过反射实例化配置类的对象。
在这里插入图片描述
所以,@EnableAutoConfiguration自动配置的实现流程就是:借助SpringFactoriesLoader从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后加载到IoC容器中。

SpringBoot的执行原理

从main方法中的SpringApplication.run()方法点进去,
在这里插入图片描述
先创建一个SpringApplication的实例,再调用实例的run方法。先看看构造方法
在这里插入图片描述

  • 是否需要创建一个web形式的ApplicationContext是根据classpath里面是否存在某个特征类(org.springframework.web.context.ConfigurableWebApplicationContext)来决定的
  • 加载ApplicationContextInitializer是使用SpringFactoriesLoader在应用的classpath中查找并加载的,它找的还是jar包里面的 META-INF/spring.factories 这个文件
  • 加载ApplicationListener也是使用SpringFactoriesLoader在应用的classpath中查找并加载的,也是找的jar包里面的 META-INF/spring.factories 这个文件

再看看 run 方法
在这里插入图片描述
该方法的几个主要步骤如下:

  1. 创建了应用的监听器SpringApplicationRunListeners并开始监听
  2. 加载SpringBoot配置环境(ConfigurableEnvironment),如果是通过web容器发布,会加载StandardEnvironment,其最终也是继承了ConfigurableEnvironment
  3. 配置环境(Environment)加入到监听器对象中
  4. 创建run方法的返回对象:ConfigurableApplicationContext(应用配置上下文)
  5. 将listeners、environment、applicationArguments、banner等重要组件与上下文对象关联
  6. refreshContext(context)方法,配置各种bean的实例化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值