深入剖析 Spring Boot 自动装配原理:从注解到实现的全流程解析
1、前言:为什么需要自动装配?
在传统的 Spring 应用中,我们需要编写大量的 XML 配置文件或使用 Java Config 来手动配置各种 Bean。随着微服务架构的流行,一个应用可能需要集成数十个 starter 依赖,如果每个都需要手动配置,那将是开发者的噩梦。
Spring Boot 的自动装配(Auto-configuration)正是为了解决这个问题而生。它通过约定大于配置的理念,让开发者只需添加依赖,就能自动获得所需的配置。
2、自动装配是什么及作用
springboot的自动装配实际上就是为了从spring.factories文件中获取到对应的需要进行自动装配的类,并生成相应的Bean对象,然后将它们交给spring容器来帮我们进行管理
3、spring自动装配的原理
3.1、启动类上注解的作用
@SpringBootApplication
这个注解是springboot启动类上的一个注解,是一个组合注解,也就是由其他注解组合起来,它的主要作用就是标记说明这个类是springboot的主配置类,springboot应该运行这个类里面的main()方法来启动程序

这个注解主要由三个子注解组成:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan

@SpringBootApplicationConfiguration
这个注解包含了@Configuration,@Configuration里面又包含了一个@Component注解,也就是说,这个注解标注在哪个类上,就表示当前这个类是一个配置类,而配置类也是spring容器中的组件


@EnableAutoConfiguration
这个注解是开启自动配置的功能,里面包含了两个注解
- @AutoConfigurationPackage
- @Import(AutoConfigurationImportSelector.class)

@AutoConfigurationPackage
这个注解的作用说白了就是将主配置类(@SpringBootApplication标注的类)所在包以及子包里面的所有组件扫描并加载到spring的容器中,这也就是为什么我们在利用springboot进行开发的时候,无论是Controller还是Service的路径都是与主配置类同级或者次级的原因。

@Import(AutoConfigurationImportSelector.class)
上一个注解我们把所有组件都加载到了容器里面,这个注解就是将需要自动装配的类以全类名的方式返回,那是怎么找到哪些是需要自动装配的类呢?
- AutoConfigurationlmportSelector是 Spring Boot中一个重要的类,它实现了ImportSelector接口, 核心使命是按照特定规则筛选并导入符合条件的自动配置类,让 Spring Boot 能 “自动” 完成大量配置工作,无需开发者手动编写 XML 或 Java 配置。
- 它的工作可以拆解为以下关键步骤,按执行顺序梳理:
1.加载自动配置类的候选列表
首先读取 Spring Boot 内置的
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件(Spring Boot 2.7+ 版本,旧版本是 spring.factories),这个文件里列出了所有内置的自动配置类(比如 DataSourceAutoConfiguration、WebMvcAutoConfiguration 等)。
这一步的核心是拿到所有候选自动配置类的全限定类名,是后续筛选的基础。
2.筛选符合条件的自动配置类
这是最核心的工作,会根据以下规则过滤掉不需要的配置类:
1)条件注解过滤:检查自动配置类上的 @Conditional 系列注解(如 @ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty 等),只有满足条件的类才会被保留。例如:DataSourceAutoConfiguration 会检查类路径下是否有 JDBC 相关类,没有则跳过该配置。
- 排除用户通过 @SpringBootApplication(exclude = ...) 主动指定排除的配置类;
- 排除通过配置项 spring.autoconfigure.exclude 指定的配置类;
- 排除不符合当前环境的配置类(比如非 Web 环境排除 Web 相关自动配置)
- 排序并导入最终的自动配置类
- 对筛选后的自动配置类按优先级排序(比如通过 @AutoConfigureOrder、@Order 注解,或内置的排序规则),确保配置加载的顺序符合依赖逻辑(比如数据源配置要先于事务配置)。
- 把最终筛选、排序后的自动配置类全限定名返回给 Spring 容器,Spring 会将这些类作为配置类加载,完成 Bean 的自动注册。
- 辅助工作:处理配置元数据
- 加载自动配置类的元数据(比如配置项的说明、默认值、是否必填等),这些元数据会用于 IDE 提示、配置校验等场景,提升开发体验。

@ComponentScan
这个注解在Spring中很重要,它对应XML配置中的包扫描配置。
作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到ioc容器中扫描该注解定义的类所属的包及其子包中的类中注解(@Controller@Service……)
3.2、springboot自动装配的流程
1、在springboot启动的时候会创建一个SpringApplication对象,在对象的构造方法里面会进行一些参数的初始化工作,最主要的是判断当前应用程序的类型以及设置初始化器以及监听器,并在这个过程中会加载整个应用程序的spring.factories文件,将文件中的内容放到缓存当中,方便后续获取;
2、SpringApplication对象创建完成之后会执行run()方法来完成整个应用程序的启动,启动的过程中有两个最主要的方法prepareContext()和refreshContext(),在这两个方法中完成了自动装配的核心功能,在run()方法里还执行了一些包括上下文对象的创建,打印banner图,异常报告期的准备等各个准备工作,方便后续进行调用;
3、在prepareContext()中主要完成的是对上下文对象的初始化操作,包括属性的设置,比如设置环境变量。在整个过程中有一个load()方法,它主要是完成一件事,那就是将启动类作为一个beanDefinition注册到registry,方便后续在进行BeanFactoryPostProcessor调用执行的时候,可以找到对应执行的主类,来完成对@SpringBootApplication、@EnableAutoConfiguration等注解的解析工作;
4、在refreshContext()方法中会进行整个容器的刷新过程,会调用spring中的refresh()方法,refresh()方法中有13个非常关键的方法,来完成整个应用程序的启动。而在自动装配过程中,会调用的关键的一个方法就是invokeBeanFactoryPostProcessors()方法,在这个方法中主要是对ConfigurationClassPostProcessor类的处理,这个类是BFPP(BeanFactoryPostProcessor)的子类,因为实现了BDRPP(BeanDefinitionRegistryPostProcessor)接口,在调用的时候会先调用BDRPP中的postProcessBeanDefinitionRegistry()方法,然后再调用BFPP中的postProcessBeanFactory()方法,在执行postProcessBeanDefinitionRegistry()方法的时候会解析处理各种的注解,包含@PropertySource、@ComponentScan、@Bean、@Import等注解,最主要的是对@Import注解的解析;
5、在解析@Import注解的时候,会有一个getImport()方法,从主类开始递归解析注解,把所有包含@Import的注解都解析到,然后在processImport()方法中对import的类进行分类,例如AutoConfigurationImportSelect归属于ImportSelect的子类,在后续的过程中会调用DeferredImportSelectorHandler类里面的process方法,来完成整个EnableAutoConfiguration的加载。
更多推荐




所有评论(0)