一、什么是自动装配
自动装配是指应用程序启动时由容器自动扫描和装配相关的组件和模块,无须像传统的spring那样在xml文件中手动配置Bean,从而简化了应用程序的配置过程,提高开发效率。
二、@SpringBootApplication解析
进入到这个 @SpringBootApplication 注解中可以看到 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 三个注解,SpringBoot的自动装配主要是由这三个注解共同来实现。
2.1 @SpringBootConfiguration
@SpringBootConfiguration的作用是标记该类为配置类,在该注解中包含 @Configuration注解。
这个@Configuration注解就是JavaConfig形式的Spring Ioc容器的配置类,JavaConfig与传统的XML配置的区别如下:
(1)基于JavaConfig的配置方式如下:
(2)基于XML配置的方式如下:
2.2 @EnableAutoConfiguration
(1)在@EnableAutoConfiguration注解中有一个@AutoConfigurationPackage注解以及一个@Import 注解,并且在@Import 注解中导入了一AutoConfigurationImportSelector.class类。@AutoConfigurationPackage注解的作用是将添加该注解的类所在的package作为自动配置package进行管理,最关键的是@Import 注解导入的这个AutoConfigurationImportSelector.class类,这个类的作用就是将需要装配的类装配到IOC容器中,也就是SpringBoot实现自动装配最核心的地方。
(2)AutoConfigurationImportSelector.class 类中最核心的方法则是selectImports()
,这个方法主要是读取META-INF/spring.factories
文件,经过去重、过滤,等操作后将需要装配的配置的类集合返回给IOC容器并将这些类注册为bean。
(3)spring.factories
文件需要在pom.xml文件中引入spring-boot-actuator-autoconfigure
这个stater,在这个stater里面的META-INF目录下。
2.3 @ComponentScan
@ComponentScan注解作用是实现启动时扫描启动类所在的包以及子包下所有标记为bean的类交由IOC容器注册为bean。可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。所以SpringBoot的启动类最好是放在root package下,尽可能把所有的类都交由IOC容器去自动装配。
三、自动装配失败的可能情况
- 类没有被正确的扫描到:Spring Boot默认只会扫描启动类所在的包以及子包下的类,如果你的类不在这个路径下,那么Spring Boot就无法自动装配到容器中。
- 类没有被正确的标记:Spring Boot使用@ComponentScan注解来扫描类,如果你的类没有被正确的标记为@Component,@Controller,@Service等,那么Spring Boot就无法自动装配到容器中。
- 依赖冲突:如果你的项目中有多个版本的依赖存在冲突,Spring Boot可能无法正确处理这些依赖,这可能导致自动装配失败。
四、总结
SpringBoot自动装的实现主要是由启动类的@SpringBootApplication
注解中的@SpringBootConfiguration
,@EnableAutoConfiguration
,@ComponentScan
三个注解共同完成自动装配;
@SpringBootConfiguration
注解标记启动类为配置类;@ComponentScan
注解实现启动时扫描启动类所在的包以及子包下所有标记为bean的类由IOC容器注册为bean;@EnableAutoConfiguration
通过@Import
注解导入AutoConfigurationImportSelector
类,然后通过AutoConfigurationImportSelector
类的selectImports
方法去读取需要被自动装配的组件依赖下的spring.factories
文件配置的组件的类全名,并按照一定的规则过滤掉不符合要求的组件的类全名,将剩余读取到的各个组件的类全名集合返回给IOC容器并将这些组件注册为bean。