Java-sdk的开发

前言

在公司的开发中, 我们经常会开发一些jar供其他业务小组使用, 在当前 spring 为主的开发环境下, 我们应该如何去包装一个jar让大家更加方便的使用呢?这里就涉及到sdk的开发, 比如kafka出品的 kafka-client 提供核心业务代码, 然后用 spring-kafka 包装 kafka-clientspring 更加方便的调用。这里我们模仿这种思路做一个简单的sdk开发流程介绍。

kafka-client的开发

我们通过构造方法简单的读取参数来模拟一个 kafka-client, 能够将读取的变量打印出来即可。

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
32
/**
* @author cc
* @description 模拟一个客户端sdk
* @date 2020-12-30
*/
public class KafkaClient {

public KafkaClient(Properties properties) {
this(propsToMap(properties));
}

KafkaClient(Map<String, Object> configs) {
ClientConfig config = new ClientConfig(configs);
}

private static Map<String, Object> propsToMap(Properties properties) {
Map<String, Object> map = new HashMap(properties.size());
Iterator var2 = properties.entrySet().iterator();

while(var2.hasNext()) {
Map.Entry<Object, Object> entry = (Map.Entry)var2.next();
if (!(entry.getKey() instanceof String)) {
throw new RuntimeException(entry.getKey().toString() + entry.getValue() + "Key must be a string.");
}

String k = (String)entry.getKey();
map.put(k, properties.get(k));
}

return map;
}
}

配置文件对象

1
2
3
4
5
6
7
public class ClientConfig extends AbstractConfig{

public ClientConfig(Map<String, Object> props) {
super(props, true);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
public class AbstractConfig {

Logger logger = Logger.getLogger("AbstractConfig");

public AbstractConfig(Map<?, ?> originals, boolean doLog) {
for (Map.Entry<?, ?> entry : originals.entrySet()) {
if (doLog) {
logger.info("读取到配置文件:[" + entry.getKey() + ":" + entry.getValue() + "]");
}
}
}
}

然后我们测试下效果

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

/**
* 1月 03, 2021 12:55:48 下午 cn.idea360.AbstractConfig <init>
* 信息: 读取到配置文件:[name:admin]
* 1月 03, 2021 12:55:48 下午 cn.idea360.AbstractConfig <init>
* 信息: 读取到配置文件:[password:123456]
*
* @param args
*/
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("name", "admin");
properties.setProperty("password", "123456");
new KafkaClient(properties);
}
}

由结果可见,我们的sdk已经可以正常使用, 将jar打包进我们的本地maven仓库, 接下来我们来包装spring-boot-adapter

kafka-spring-boot-starter开发

我们自定义的starter要遵守官方推荐的命名规范 xxx-spring-boot-starter
在我们使用开源社区提供的jar包时发现,好多变量在配置的时候是有提示补全功能的,这个我们也来实现下。

  1. 首先引入pom.xml依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>cn.idea360</groupId>
<artifactId>idea360-kafka-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
  1. 创建配置类

@ConfigurationProperties 注解即是配置变量补全的关键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
@ConfigurationProperties(prefix = "idea360.kafka")
public class DemoProperties {

private String name;
private String password;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}
  1. 将配置信息注入sdk的bean对象 kafka-client
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
@EnableConfigurationProperties(DemoProperties.class)
public class DemoConfig {

@Bean
public KafkaClient kafkaClient(DemoProperties demoProperties) {
Properties properties = new Properties();
properties.setProperty("name", demoProperties.getName());
properties.setProperty("password", demoProperties.getPassword());
return new KafkaClient(properties);
}
}
  1. 按照spring的spi机制定义自启动类。 在 src/main/resources/META-INF/spring.factories 文件中定义
1
org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.idea360.starter.DemoConfig
  1. 将我们包装好的starter打包进本地maven仓库

自定义starter测试

  1. 创建一个普通的spring-boot项目, pom.xml如下
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.idea360</groupId>
<artifactId>idea360-kafka-spring-boot-demo</artifactId>
<version>0.0.1</version>
<name>dea360-kafka-spring-boot-demo</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>idea360-kafka-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>cn.idea360.springdemo.SpringDemoApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
  1. 配置application.properties
1
2
3
4
5
6
7
# 应用名称
spring.application.name=idea360-kafka-spring-boot-demo
# 应用服务 WEB 访问端口
server.port=8080

idea360.kafka.name=admin
idea360.kafka.password=123456

这里我们看到已经可以自动提示补全参数了

  1. 启动springboot项目, 控制台我们看到上边我们配置的参数已经被正确注入到了 kafka-client 中。
1
2
2021-01-03 13:10:53.402  INFO 13169 --- [           main] AbstractConfig                           : 读取到配置文件:[name:admin]
2021-01-03 13:10:53.402 INFO 13169 --- [ main] AbstractConfig : 读取到配置文件:[password:123456]

最后

本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。