Spring Boot-23-自定义starter

本文来了解一下 Spring Boot 中的 starter, starter 是 Spring Boot 中的一个可拔插的插件,需要使用的时候只要引入对应的包, 比如我们要使用web环境,就会引入 spring-boot-starter-web

starter 和 jar包导入的区别就是 starter 可以实现自动注入, 而jar包只会把对应的类导入,并不会加载到容器中, 所以 starter 可以大幅提升开发效率

常用的starter

名称 描述
spring-boot-starter-thymeleaf 使MVC Web Application 支持 Thymeleaf
spring-boot-starter-mail 提供 Java Mail 和 Spring email 的发送支持
spring-boot-starter-data-redis 通过 Spring Data Redis/Jedis client 使用 Redis
spring-boot-starter-web 提供web支持

自定义 starter 搭建

下面我们来搭建一个自定义的 starter

首先新建一个项目 spring-boot-starter-weather , 然后引入 spring-boot-autoconfigure 这个包

新建类 WeatherSource 代码如下:

1
2
3
4
5
6
7
8
9
@Data
@ConfigurationProperties(prefix = "weather")
public class WeatherSource {

private String type;

private String rate;

}

再建一个 WeatherService 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class WeatherService {

private WeatherSource weatherSource;

public WeatherService(WeatherSource weatherSource) {
this.weatherSource = weatherSource;
}

public String getType(){
return weatherSource.getType();
}

public String getRate(){
return weatherSource.getRate();
}

}

然后还需要一个自动装配的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
@EnableConfigurationProperties(WeatherSource.class)
@ConditionalOnProperty(name = "weather.enable", havingValue = "enable")
public class WeatherAutoConfiguration {

@Autowired
private WeatherSource weatherSource;

@Bean
@ConditionalOnMissingBean(WeatherService.class)
public WeatherService weatherService(){
return new WeatherService(weatherSource);
}

}

这个类意思是属性中必须存在 weather.enable 且值是 enable 的情况下才生效,且在容器中不存在 WeatherService 这个类的时候才注入我们默认的 WeatherService

然后最重要的一步,在 Resource 目录下新建 META-INF 目录,然后新建 spring.factories 文件内容如下

1
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zhou.springboot.starter.weather.WeatherAutoConfiguration

就是把我们上面的配置类写进去

然后 maven 打包把jar装到本地,就可以在别的项目中引入这个包使用了

注意记得配置 weather.enable=enable 才会生效

原理解析

上面我们实现了自定义的 stater ,那么 starter 的实现原理是怎么样的,下面来看一下

在 web 容器启动的时候,我们对 @EnableAutoConfiguration 这个注解做了分析, 在处理 @Import 注解的时候, 会进入下面这个代码段

image

这段代码我们在之前详细的分析过了

image

这里就会找到所有的 EnableAutoConfiguration 的实现,然后加载到容器中

所以我们上面才会新建一个 spring.factories 文件,把实现类写进去

总结

了解了 starter 的作用后,我们自定义实现了一个 starter

自定义 starter 的步骤:

  1. 新建一个 Spring Boot 项目
  2. 引入 spring-boot-autoconfigure
  3. 编写属性源以及自动配置类
  4. spring.factories 里添加自动配置类实现
  5. 打成jar包供外部使用

自动配置流程:

  1. 启动类的 @SpringBootApplication 注解
  2. 处理 @EnableAutoConfiguration 注解 Import 的 AutoConfigurationImportSelector
  3. ConfigurationClassParser 处理配置类
  4. 获取 spring.factories 里面的所有 EnableAutoConfiguration 的实现类然后处理