引入Starter
以引入 **spring-boot-starter-web **为例
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 在引入spring-boot-starter-web后,这被称为web场景启动器,会引入很多基础的服务
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.5.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.5.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.12</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
- 每个 starter服务中都会引入 spring-boot-starter,每一个场景启动器都会引入,这被称为核心场景启动器
- 每一个spring-boot-starter中都会引入 spring-boot-autoconfigure,这其中包括了核心场景的所有配置。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.6</version>
<scope>compile</scope>
</dependency>
�
- 其中包含各个场景的配置文件,配置文件的本质是包含着 @Configuration 注解的文件,其中的作用是包含许多 @Bean ,将所需的组件作为Bean加入到Spring容器中
- 因此只需要引入starter后,文件中就会包含这些配置文件类,但此时这些配置文件不会被扫描到,因此Springboot默认扫描组件的范围只是启动类所在的包及其子包,因此这些配置文件不会被扫描到,因此其中的Bean也不会注册到容器中
扫描组件
- 在Springboot程序中,需要在启动类上添加@SpringbootApplication注解
- 该注解由多个注解组成
@SpringBootConfiguration //与@Configuration相等
@EnableAutoConfiguration //自动装配
@ComponentScan //组件扫描 扫描启动类所在的包路径
- 在@EnableAutoConfiguration 注解中会通过@Import注解引入AutoConfigurationImportSelector,这会批量的引入组件
@Import({AutoConfigurationImportSelector.class})
- 在AutoConfigurationImportSelector类中,启动时会通过 getCandidateConfigurations方法获取所有需要导入的类名,这些类名保存在 META-INF/spring.factories中
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
}
- 根据文件中的全类名,SpringBoot就会去导入这些相关的配置文件类
- 并不是所有的配置文件类都会被导入,配置文件类中以及Bean注解中包含Condition相关注解,只有满足相关条件才会加载配置文件
- 在配置文件中包含@EnableConfigurantionProperties注解,这个注解会使@ConfigurationProperties生效,这个注解会将配置文件类与 properties文件进行绑定,同时将该Properties作为Bean加入到容器中,因此做到可以在Properties中配置属性,导入的组件能够读取到Properties中配置的属性。