简介
Spring Boot已经为很多的开源项目提供了很多的 starter项目,你也可以开发你自定义的 starter。再开始之前让我们先理解下Spring Boot是如何自动配置的,如果你已经知道 Spring Boot自动配置的过程可以直接调到创建自定义starter步骤。
Spring Boot 自动配置
当你启动 Spring Boot 应用的时候,Spring Boot 会检测一个特殊的文件,它是 spring-boot-autoconfigure 这个包内的META-INF/spring.factories
它里面的内容我们重点关注这里
这里是利用的spring SPI提供的扩展机制。
这里简单介绍下 SPI (全称Service Provider Interface),是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。 SPI的作用就是为这些被扩展的API寻找服务实现。
通俗一点讲就是SPI 就是服务方提供接口,具体的实现由其他方来实现,只需要将实现了的类全路径加入到文件中,服务方启动的时候就会把这些文件内容解析出来,由于配置了类全路径地址,直接利用反射机制将这些类初始化提供使用。
开始创建自定义的starter
- 创建一个Spring Boot 项目,在pom.xml中引入
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.2.2.RELEASE</version> </dependency>
|
- 创建一个类 。该类starter 引入后自动加入到 Spring 容器中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class HelloService { private String prefix; private String suffix; public HelloService() { } public HelloService(String prefix, String suffix) { this.prefix = prefix; this.suffix = suffix; }
public String sayHello(String word) { return prefix + word + suffix; } }
|
- 创建一个配置类,提供 starter 引入方自定义属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| //prefix = "hello" 引入 starter 的项目配置文件的前置是 hello @ConfigurationProperties(prefix = "hello") public class HelloProperties { private String prefix; private String suffix;
public String getPrefix() { return prefix; }
public void setPrefix(String prefix) { this.prefix = prefix; }
public String getSuffix() { return suffix; }
public void setSuffix(String suffix) { this.suffix = suffix; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| /** * @Configuration 定义当前类是个配置类 * @ConditionalOnClass,当classpath下发现该类(HelloService)的情况下进行自动配置。 * @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。 * @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"), * 当配置文件中example.service.enabled=true时将这个类创建为一个 Spring Bean * @EnableConfigurationProperties(HelloProperties.class) 让使用 @ConfigurationProperties 注解的类生效 */ @Configuration @ConditionalOnClass(HelloService.class) @EnableConfigurationProperties(HelloProperties.class) public class HelloAutoConfiguration {
@Autowired private HelloProperties helloProperties;
@Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "hello", value = "enable", havingValue = "true") HelloService helloService() { return new HelloService(helloProperties.getPrefix(),helloProperties.getSuffix()); } }
|
- 在/resources/META-INF/spring.factories 创建这个文件
文件写入内容
1
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.yefan.hello.HelloAutoConfiguration
|
- 创建另外一个Spring Boot 项目,像引入其他 starter 方式引入上面创建的 maven 依赖
1 2 3 4 5
| <dependency> <groupId>com.yefan.study</groupId> <artifactId>hello-spring-boot-starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
|
1 2 3 4
| hello: enable: true prefix: xxx suffix: xxx
|
1 2
| @Autowired HelloService helloService;
|