构建一个自定义的spring-boot-starter

前言

现在很多项目都使用SpringBoot构建了,不知道大家在使用SpringBoot项目时有没有注意到它的一些jar包的引用。如下图:

upload successful

我们引入相关starter后,在application.properties或者application.yml里面进行相关配置,便可以尽情使用相关功能了,十分方便。

今天我们构建一个自己的spring-boot-starter,来体验下spring-boot的魅力和乐趣。

正文

我之前有一篇文章是ElasticSearch的介绍并且对它的Java客户端封装了下,那个例子中我们最后的配置文件叫property/es-config.properties 不知道大家还有没有印象。要使用那个jar包,我们需要配置一个es-config.properties文件,显然,我想去掉这个文件,改为application.properties的那种配置,和各种spring-boot-starter一样。

好了,我们开始吧。

创建项目

首先,我们需要创建一个名为 elasticsearch-spring-boot-starter 的SpringBoot项目(除springboot基础外不需要其他dependencies)。

upload successful

这儿有一点要注意的,就是项目(后面生成jar包)命名。

备注:Spring官方的starter命名一般会采用 spring-boot-starter-xxxx的形式,而官方建议非官方的starter命名可以遵循 xxxx-spring-boot-starter的形式。

引入依赖

然后我们引入我们要编写的starter的一些依赖。(这里对以前封装的ElasticSearch 客户端jar包进行继续优化封装)

upload successful

备注:dependency里的optional表示可选依赖,因为spring-boot父项目有日志的相关jar,我们不必再次引用。

这样配置的优点大致如下:

  1. 节约空间(不用两个jar包重复引用)
  2. 避免license许可问题(两个jar版本不同可能出现问题)
  3. 避免jar包出现冲突等问题(两个jar版本不同可能出现问题)

构建(改造)项目

然后我们把原来的项目改造下。

我们移除了配置解析的一些方法及类,改用自动配置。

upload successful

使用@ConfigurationProperties注解,指定要进行属性配置的Bean。

upload successful

使用该注解,需要引入下面的jar包。

upload successful

这个jar包的@ConfigurationProperties注解可以帮我们把application.properties的属性值映射到Bean里。

这个jar的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给IDE使用,可以进行友好的提示。

我们还需要创建一个自动配置类,名为ElasticSearchStarterAutoConfigure,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
@ConditionalOnClass(ElasticSearchClientFactory.class)
@EnableConfigurationProperties(ElasticSearchConfiguration.class)
public class ElasticSearchStarterAutoConfigure {
@Autowired
private ElasticSearchConfiguration properties;

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.elasticserch.zwt", name = "enabled", havingValue = "true")
ElasticSearchUtil elasticSearchUtil (){
ElasticSearchClientFactory elasticSearchClientFactory=new ElasticSearchClientFactory(properties);
return new ElasticSearchUtil(elasticSearchClientFactory);
}
}

@Configuration注解,我们可以看到它被标识为 @Component注解,可以认为它最终也会成为spring容器里的一个Bean。

upload successful

@ConditionalOnClass 当指定class存在时进行Bean创建。

@EnableConfigurationProperties 为指定class启用属性配置。

@ConditionalOnMissingBean 当bean不存在时进行bean创建。

@ConditionalOnProperty 用属性对bean进行配置创建。它里面可以enabled可以控制是否启用我们的配置。

然后在resources/META-INF 文件夹下新建spring.factories文件,添加如下内容,用于Spring加载自动配置类。

1
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zwt.elasticsearchspringbootstarter.factory.ElasticSearchStarterAutoConfigure

配置完成后,在application.properties里,就可以看到我们的自定义属性啦。

upload successful

测试

创建测试类进行测试。

upload successful

application.properties配置如下:

1
2
3
4
## es地址
spring.elasticserch.zwt.address=127.0.0.1:9300
## 是否启用es客户端
spring.elasticserch.zwt.enabled=true

可以看到我们的日志输出。

upload successful

当我们把spring.elasticserch.zwt.enabled设置为false时,在运行可以看到bean创建失败了,即未注入属性配置bean。

upload successful

提升

我们把项目用maven打包发布下(clean install),可以看到大约30多M…….

upload successful

原因是它里面有原始的springboot项目,还内置了tomcat等,我们如果想把该工具jar包引入到另一个springboot项目里,这显然是不合理的。

我们还需要对其进行优化。

我们删除无用的Application class(springboot启动使用,显然我们封装jar包不是为了封装web项目),application.properties(当我们把我们工具jar引入到新的springboot项目里,里面已经有了application.properties)及test类包。

然后处理下pom文件。

在pom文件里,spring-boot-starter这个依赖我们是不需要打到包里的。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

将其添加属性。

1
<optional>true</optional>

同时build插件做下调整(原来用的springboot的插件)。

build插件基本固定的,代码可以不用看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<source>${java.version}</source>
<target>${java.version}</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

再次编译,这时候我们就可以看到jar包大小只有10几Kb啦。

upload successful

应用

我们随便创建一个新的springboot项目。引入我们封装的jar包。

upload successful

配置application.properties文件

1
2
3
4
## es地址
spring.elasticserch.zwt.address=127.0.0.1:9300
## 是否启用es客户端
spring.elasticserch.zwt.enabled=true

新建个测试类,对我们的jar包进行测试。
可以看到正常运行。

upload successful

总结

通过一步步改造,我们成功创建了一个spring-boot-starter。

通过实践,我们也能看到springboot基于注解简化代码的配置。也是蛮不错的一次工具封装体验。

补充:上面说的@ConfigurationProperties注解也可以定义自己的配置文件。

如果我们想使用原来的es-config.properties则需要进行如下配置即可。

upload successful

PS:SpringBoot官方已经有了对elasticsearch client的支持,建议使用官方相关支持工具。

自己实践时,可以简单的写一个HelloWorld去完成一个简单的spring-boot-starter的封装。

相关代码: https://github.com/JavaZWT/framework-base/tree/master/elasticsearch-spring-boot-starter




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

您的支持就是我创作的动力!

欢迎关注我的其它发布渠道