Spring Boot 自定义腾讯位置服务 WebService API Starter
本章节将介绍如何自定义 Spring Boot Starter,并且结合 Github Actions 自动上传 Maven 中央仓库。
📍 腾讯位置服务 WebService API Spring Boot Starter (🌟 点个 star ,不迷路)
前言
最近有一个需求,需要对接腾讯位置服务 WebService API,但找来找去发现官方并没有提供 Java SDK,考虑到后续其他项目也会有这个需求后,干脆索性自己封装一个 starter,并希望上传 Maven 中央仓库,实现像集成 MyBatis Plus 一样方便,直接引入依赖即可,让 Spring Boot 完成自动装配,并不需要关心具体配置以及代码,实现松耦合。
自定义
命名规范
Spring 官方提供 starter 通常命名为 spring-boot-starter-{name} :

Spring 官方建议非官方提供的 starter 命名应遵守 {name}-spring-boot-starter 格式
比如 mybatis 出品:mybatis-spring-boot-starter

创建项目
starter 是基于 Spring Boot 项目创建而成,使用 IDEA 初始化 Spring Boot 项目后,删除 src 文件夹,并新建两个 Module,分别是 {name}-spring-boot-starter(启动器) 以及 {name}-spring-boot-autoconfigure(自动配置包),新建完成后删除启动类。
文件夹命名规范参考:mybatis-spring-boot-starter,项目架构大致如下:
├─pom.xml
│
├─lbs-spring-boot-autoconfigure
│ │ pom.xml
│ │
│ └─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─starimmortal
│ │ │
│ │ └─resources
│ └─test
│ └─java
└─lbs-spring-boot-starter
│ pom.xml
│
└─src
├─main
│ ├─java
│ │ └─com
│ │ └─starimmortal
│ │
│ └─resources
└─test
└─java




提示:最终版本包含了 lbs-client-core 业务核心模块,在这里没有体现,根据个人开发习惯不同,可以选择将业务代码写在
{name}-spring-boot-autoconfigure下,但这里还是推荐将业务核心功能单独封装成一个模块。
模块依赖
<?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>
<packaging>pom</packaging>
<modules>
<module>lbs-client-core</module>
<module>lbs-spring-boot-starter</module>
<module>lbs-spring-boot-autoconfigure</module>
</modules>
<groupId>com.starimmortal</groupId>
<artifactId>lbs-spring-boot</artifactId>
<version>1.0.0</version>
<name>lbs-spring-boot</name>
<description>Tencent LBS WebService API Spring Boot Starter</description>
<url>https://github.com/ElanYoung/lbs-spring-boot/tree/main</url>
<properties>
<argLine>-Dfile.encoding=UTF-8</argLine>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<spring-boot-dependencies.version>2.7.12</spring-boot-dependencies.version>
<lombok.version>1.18.28</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Lombok 插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
开源项目强烈建议使用 dependencyManagement 来管理 Maven 依赖,否则可能会出现版本兼容问题!
{name}-spring-boot-autoconfigure
注意:lbs-client-core 模块是单独封装好腾讯位置服务 WebService API 业务核心模块,大家可以根据自己不同业务创建底层核心模块。
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>lbs-spring-boot</artifactId>
<groupId>com.starimmortal</groupId>
<version>1.0.0</version>
</parent>
<artifactId>lbs-spring-boot-autoconfigure</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 客户端核心功能 -->
<dependency>
<groupId>com.starimmortal</groupId>
<artifactId>lbs-client-core</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 自动配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- Configuration Processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
{name}-spring-boot-starter
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<parent>
<artifactId>lbs-spring-boot</artifactId>
<groupId>com.starimmortal</groupId>
<version>1.0.0</version>
</parent>
<artifactId>lbs-spring-boot-starter</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Spring Boot 自动配置 -->
<dependency>
<groupId>com.starimmortal</groupId>
<artifactId>lbs-spring-boot-autoconfigure</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
配置属性类
提示:此配置属性类作用将体现在 application.yml 配置文件上。
LbsProperties 是一个配置实体类,里面包含了腾讯位置服务 WebService API 相关配置项。
使用 @ConfigurationProperties 注解,会自动把 application.yml 文件中以 lbs 前缀开头外部属性跟 LbsProperties 中类字段进行绑定,自动注入到 LbsProperties 对象中。
@ConfigurationProperties(prefix = LbsProperties.LBS_PREFIX)
public class LbsProperties {
/**
* 属性前缀
*/
public static final String LBS_PREFIX = "lbs";
/**
* 密钥
*/
private String key;
/**
* 签名校验
*/
private String sk;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getSk() {
return sk;
}
public void setSk(String sk) {
this.sk = sk;
}
}
自动配置类
LbsAutoConfiguration 类使用了 @Configuration 注解标记为配置类,并且使用 @EnableConfigurationProperties 注解会自动注入 LbsProperties 类实例。
此外,最关键点在于该类里面创建了 lbsClient bean实例,这是自动配置精髓。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(LbsProperties.class)
public class LbsAutoConfiguration {
private final LbsProperties lbsProperties;
public LbsAutoConfiguration(LbsProperties lbsProperties) {
this.lbsProperties = lbsProperties;
}
@Bean
public LbsClient lbsClient() {
return new LbsClient(lbsProperties.getKey(), lbsProperties.getSk());
}
}
提示:
LbsClient类属于 lbs-client-core 模块中主要核心代码,里面封装了腾讯位置服务 WebService API 相关接口。
spring.factories
为了实现自动装配,需在 {name}-spring-boot-autoconfigure 模块中的 resources 目录下新建 META-INF 文件夹,然后创建 spring.factories 文件,并写入以下内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.starimmortal.lbs.autoconfigure.LbsAutoConfiguration
注意:Spring Boot 2.7 已经标记 spring.factories 加载自动化配置方式为过期,Spring Boot 3 中将完全移除原有方式。
为了上下兼容,需在 META-INF 目录下创建 spring 文件夹,并且新建 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,写入以下内容:
com.starimmortal.lbs.autoconfigure.LbsAutoConfiguration
├── src
│ └── main
│ └── resources
│ ├── META-INF
│ │ └── spring
│ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports

打包安装
mvn clean install
测试
引入依赖
<dependency>
<groupId>com.starimmortal</groupId>
<artifactId>lbs-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
参数配置
# 腾讯位置服务
lbs:
# 开发者密钥
key: OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77
# 签名校验
sg: ER1w0iqvajsow4a5tAC7OPfBVboHzMe
IP定位
import com.starimmortal.lbs.LbsClient;
import com.starimmortal.lbs.response.IpLocationResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/lbs")
public class LbsController {
@Autowired
private LbsClient lbsClient;
@GetMapping("/ip")
public IpLocationResponse ipLocation() {
return lbsClient.ipLocation("221.224.9.195");
}
}

发布 Maven 中央仓库
准备 Sonatype 账号
创建命名空间
博主 Github 地址:github.com/ElanYoung
myusername ->
elanyoung命名空间 ->
io.github.elanyoung
| Service | Example namespace |
|---|---|
| GitHub | io.github.myusername |
| GitLab | io.gitlab.myusername |
| Gitee | io.gitee.myusername |
| Bitbucket | io.bitbucket.myusername |
命名空间被创建后,它将以 “Unverified” 状态开始:
验证命名空间
创建一个临时公共存储库来证明帐户所有权,其名称设置为命名空间验证密钥。
在该过程结束时,您只需删除空存储库即可。仅在验证阶段需要它。
创建账号密码
<server>
<id>central</id>
<username>QHsPUT6O</username>
<password>R0a3zn6VzlEu19/KI66BtKjYvZ+vcg0rAUjFAryUr2IT</password>
</server>
${server} 定义为 central,后续 pom.xml 配置文件会用到。
注意:上述内容需复制粘贴至 Maven 配置文件 settings.xml 中!
GPG
GPG(GNU Privacy Guard) 是基于 OpenPGP 标准实现的加密软件,它提供了对文件的非对称加密和签名验证功能。所有发布到 Maven 仓库的文件都需要进行 GPG 签名,以验证文件的合法性。
安装
Mac
brew install gpg
Windows




生成 GPG 密钥对
# 密钥生成命令
gpg --generate-key
# 密钥查看命令
gpg --list-keys


删除 GPG 密钥对
# 删除私钥
gpg --delete-secret-keys <pub字符串>
# 删除公钥
gpg --delete-keys <pub字符串>
上传公钥
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --send-keys <pub字符串>

验证公钥
gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-keys <pub字符串>

配置文件
settings.xml
配置文件路径:Maven 安装目录下
conf目录下settings.xml文件
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
<servers>
<server>
<id>central</id>
<username>QHsPUT6O</username>
<password>R0a3zn6VzlEu19/KI66BtKjYvZ+vcg0rAUjFAryUr2IT</password>
</server>
</servers>
<profiles>
<profile>
<id>central</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>your-gpg-passphrase</gpg.passphrase>
</properties>
</profile>
</profiles>
</settings>
pom.xml
1)项目信息
<groupId>com.starimmortal</groupId>
<artifactId>lbs-spring-boot</artifactId>
<version>1.0.0</version>
<name>lbs-spring-boot</name>
<description>Tencent LBS WebService API Spring Boot Starter</description>
<url>https://github.com/ElanYoung/lbs-spring-boot/tree/main</url>
2)开源协议
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
3)开发者信息
<developers>
<developer>
<name>ElanYoung</name>
<email>991658923@qq.com</email>
<organizationUrl>https://doc.starimmortal.com</organizationUrl>
</developer>
</developers>
4)版本管理
<scm>
<connection>scm:git:git://github.com/ElanYoung/lbs-spring-boot.git</connection>
<developerConnection>scm:git:ssh://github.com:ElanYoung/lbs-spring-boot.git</developerConnection>
<url>https://github.com/ElanYoung/lbs-spring-boot/tree/master</url>
</scm>
5)远程仓库
<distributionManagement>
<repository>
<id>central</id>
<url>https://central.sonatype.com/</url>
</repository>
<snapshotRepository>
<id>central</id>
<url>https://central.sonatype.com/</url>
</snapshotRepository>
</distributionManagement>
6)插件
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<!-- Source -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Javadoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<configuration>
<show>private</show>
<nohelp>true</nohelp>
<charset>UTF-8</charset>
<encoding>UTF-8</encoding>
<docencoding>UTF-8</docencoding>
<doclint>none</doclint>
<detectJavaApiLink>false</detectJavaApiLink>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Gpg Signature -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.7</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- 用于gpg非交互式密码输入 -->
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</plugin>
<!-- Central发布插件 -->
<plugin>
<groupId>org.sonatype.central</groupId>
<artifactId>central-publishing-maven-plugin</artifactId>
<version>0.7.0</version>
<extensions>true</extensions>
<configuration>
<publishingServerId>central</publishingServerId>
<checksums>required</checksums>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
打包上传
在 Profiles 选中 release,然后依次执行 clean、deploy 命令:
正式发布
更新这篇文章时,我已经发布过了,所以按钮显示灰色!
1)方式一:Sonatype Nexus 面板上查看

2)方式二:releases 中央仓库文件目录中查看

3)方式三:MavenCentral 搜索栏查找

注意事项
- publishingServerId 值要与 settings.xml 文件里 server.id 值对应;
- 每发布一次,就需要重新 Generate User Token,否则会报 401 错误;
- pom.xml 文件内容请务必填写完整!
Github Actions
前提条件
-
OSSRH 账号密码
-
GPS 私钥
1)查看私钥
gpg --list-secret-keys --keyid-format LONG

2)导出私钥
gpg --armo --export-secret-keys <私钥>
3)GPG Passphrase



配置文件
在项目根目录下新建 .github/workflows/release.yml 文件,内容如下:
name: Java CI With Maven
on:
release:
types: [ published ]
jobs:
build:
runs-on: ubuntu-latest
steps:
# 拉取源码
- uses: actions/checkout@v3
# 安装JDK环境
- name: Set up JDK 8
uses: actions/setup-java@v3
with:
java-version: '8'
distribution: 'temurin'
server-id: central
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
- name: Publish package
env:
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
run: |
cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import;
mvn clean deploy -U -P release -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} -DskipTests
Releases
提示:发布 Releases 后会自动触发 Actions

