第二节 Spring Boot项目pom文件中starter解析
1.什么是Spring Boot Strater
Spring Boot Starter是一组方便的依赖描述符,可以在应用程序中包含。它将所有的功能的依赖包都抽取出来,做成一个个的starters(启动器)。
Starter是Spring Boot的四大核心功能特性之一,Starter是启动依赖,它的主要作用为:Starter组件以功能为纬度,来维护对应的jar包的版本依赖,使得开发者可以不需要去关心这些版本冲突这种容易出错的细节。Starter组件会把对应功能的所有jar包依赖全部导入进来,避免了开发者自己去引入依赖带来的麻烦。Starter内部集成了自动装配的机制,也就说在程序中依赖对应的starter组件以后,这个组件自动会集成到Spring生态下,并且对于相关Bean的管理,也是基于自动装配机制来完成。依赖Starter组件后,这个组件对应的功能所需要维护的外部化配置,会自动集成到Spring Boot里面,我们只需要在application.properties文件里面进行维护就行了。
Starter文件也只是一个pom文件,而不是jar,它的目的也是去自动地引入其他的jar文件。
Starter的整体逻辑:
2. 如何在pom.xml文件中添加Spring Boot Starter
在pom.xml文件中添加相应依赖,例如:引入mybatis-spring-boot-starter依赖。
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
3. Spring Boot Starter运行原理
3.1 Spring Boot启动过程
Spring Boot在启动时会从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值。然后将这些值作为自动配置类导入容器,自动配置类就生效,帮助我们进行自动配置工作。
3.2 自动配置
3.2.1 自动配置类的梳理
自动配置主要通过XxxAutoConfiguration这些类来实现,如下图
上图是 DataSourceAutoConfiguration这个自动配置类,我们可以看到类上的几个注解。
- @AutoConfiguration是开发当中最常用的注解,它属于是@Component注解的扩展注解,同@Controller、@Service等几个注解的功能是一样的,只要在类上添加了该注解,然后在springboot的扫描范围内,启动项目的时候会将该注解修饰的类通过无参构造器创建出来,然后存入spring容器当中。
- @ConditionalOnClass表示某个类位于类路径上时候,才会实例化这个bean
- @ConditionalOnMissingBean,仅在当前上下文中不存在某个bean时,才会实例化这个Bean。
- @EnableConfigurationProperties注解的作用是使@ConfigurationProperties注解生效。如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component或者实现了@Component的其他注解,那么在IOC容器中是获取不到properties 配置文件转化的bean。
进入@DataSourceProperties查看
可以查看到这里使用@configurationPropertes,@ConfigurationProperties注解的作用是把yml或者properties配置文件转化为bean。
使用@ConfigurationProperties和@EnableConfigurationProperties这两个注解来完成将一个包含众多属性的类来注册成为可供springIoc容器管理的bean。 而这个bean的注册过程是在各个XXXAutoConfiguration类中完成的。
3.2.2 发现依赖包中的Bean
我们都知道springboot默认扫描启动类下面的主类和子类的bean来完成注解,但是并没有包括依赖包中的类,那么依赖包中的bean是如何被发现和加载的?
关键在于@SpringBootApplication这个注解
注解层次:
-
@SpringBootConfiguration:和@Configuration相同的用处,并且将里面通过@bean注解标注的方法的返回值作为bean对象注册到ioc容器之中。
-
获得bean的两种方式,一种是在配置类中通过方法返回,一种是直接在类上注解@bean(或者相同的注解,类似@Mapper等)来注册为bean实例
-
@EnableAutoConfiguration:借助@Import的支持,收集和注册依赖包中相关的bean定义。
-
@Import({AutoConfigurationImportSelector.class}):该注解扫描依赖包下需要注册为bean的自动配置类。
-
SpringFactoriesLoader.loadFactoryNames方法调用loadSpringFactories方法从所有的jar包中读取META-INF/spring.factories文件信息。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations =SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
- 而Spring.factories中key/value中就有一个key是:org.springframework.boot.autoconfigure.EnableAutoConfiguration,后面跟着的都是需要AutoConfigurationImportSelector来进行注册的自动配置类
- @AutoConfigurationPackage
- @Import({Registrar.class}):Registrar就是扫描启动类目录下的所有bean并且注册,具体实现通过下列代码:
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports { Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));
}
}
3.3.3 加载发现的Bean
如果要让一个普通类交给Spring容器管理,通常有以下方法:
- 使用 @Configuration与@Bean 注解
- 使用@Controller @Service @Repository @Component 注解标注该类,然后启用@ComponentScan自动扫描
- 使用@Import 方法
springboot中使用了@Import 方法
@EnableAutoConfiguration注解中使用了@Import({ AutoConfigurationImportSelector.class})注解,AutoConfigurationImportSelector实现了DeferredImportSelector接口,
DeferredImportSelector接口继承了ImportSelector接口,ImportSelector接口只有一个selectImports方法。
selectImports方法返回一组bean,@EnableAutoConfiguration注解借助@Import注解将这组bean注入到spring容器中,springboot正式通过这种机制来完成bean的注入的。
3.3 优点
有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。
只需要在项目里面引入这些starter那么实现相关功能的所有依赖都会自动导入进来,且没有版本冲突。