现在很多开源的组件都会提供对应的 springboot-starter 包给我们去用,要做一个 starter 包并不难。参照Spring内置的实现就好了:
1、在工程里引入 starter 打包相关的依赖。
2、在我们工程内建 spring.factories 文件,编写我们配置类的全限类名。

创建一个 Spring Boot Starter

1. 创建 Maven 项目

使用 Maven 创建一个新的 Spring Boot Starter 项目。

mvn archetype:generate -DgroupId=com.example -DartifactId=my-spring-boot-starter -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

2. 修改 pom.xml

在项目的 pom.xml 文件中,添加 Spring Boot 的依赖和插件配置。

<?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>

    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.boot.version>2.7.13</spring.boot.version> 
    </properties>

    <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>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3. 创建配置属性类

使用 @ConfigurationProperties 注解定义一个配置类,以便在应用中使用配置。

package com.example;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
    private String greeting = "Hello";

    public String getGreeting() {
        return greeting;
    }

    public void setGreeting(String greeting) {
        this.greeting = greeting;
    }
}

4. 创建自动配置类

src/main/java/com/example 下创建一个自动配置类,并注入配置属性。

package com.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyStarterAutoConfiguration {

    private final MyServiceProperties properties;

    public MyStarterAutoConfiguration(MyServiceProperties properties) {
        this.properties = properties;
    }

    @Bean
    public MyService myService() {
        return new MyService(properties.getGreeting());
    }
}

5. 创建服务类

创建一个简单的服务类,以使用配置的属性。

package com.example;

public class MyService {
    private final String greeting;

    public MyService(String greeting) {
        this.greeting = greeting;
    }

    public String greet() {
        return greeting + " from MyService!";
    }
}

6. 添加 spring.factories

src/main/resources/META-INF 目录下创建 spring.factories 文件,内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyStarterAutoConfiguration

7. 生成元数据

在编译项目时,spring-boot-configuration-processor 会生成 spring-configuration-metadata.json 文件。这些文件将帮助 IDE 提供配置属性的自动提示。

8. 打包和使用

使用 Maven 打包你的项目:

mvn clean package

然后在另一个 Spring Boot 项目的 pom.xml 中添加你的 Starter 依赖。

<dependency>
    <groupId>com.example</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

9. 测试配置功能

在使用你的 Starter 的项目中,创建 application.ymlapplication.properties 文件,以配置你的属性。

application.yml 示例

my:
  service:
    greeting: "Hello, World!"

在你的应用中使用服务:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class MyAppRunner implements CommandLineRunner {

    @Autowired
    private MyService myService;

    @Override
    public void run(String... args) {
        System.out.println(myService.greet());
    }
}

总结

通过以上步骤,你可以创建一个功能齐全的 Spring Boot Starter,支持自动配置和配置属性的自动提示。关键点包括:

  • 使用 @ConfigurationProperties 注解绑定配置属性。
  • 使用 spring-boot-configuration-processor 生成配置元数据。
  • 利用 spring.factories 实现自动配置。

上传 Maven 中央仓库

注册中央仓库账户

打开网址:

Maven Central

点击右上角的“登录”链接:

image-jkjh.png

中央门户支持通过 Google 或 GitHub 进行社交登录。您还可以选择自己的用户名和密码。如果您选择使用社交登录帐户进行注册,Sonatype 将有权访问与您的社交登录帐户关联的电子邮件地址。

成功授权登录github账号后,就直接登录了,点击右上角账户下拉菜单里的“View Namespaces”,能查看到自己的namespace,就像这样

image-9shk.png

然后再点击右上角账户下拉菜单里的“View Account”,进入创建token页面,点击右侧的“Generate User Token”按钮,会弹出你的token,只显示一分钟,快速将内容复制下来

image-tfcl.png

image-ideh.png

  • 这个配置内容可以直接拷贝到maven配置文件settings.xml的servers段配置里,但是请注意“${server}”必须替换为字符串“central”表示中央仓库

创建gpg密钥

确保您已经安装了GPG工具。如果没有,请访问GnuPG官方网站下载并安装。
也可以通过scoop 安装 scoop install gpg

生成GPG密钥对

gpg --gen-key

按照提示操作,创建一个密钥对,可能会要你输入密钥密码passphrase,这个密码后面也要配置到maven配置文件settings.xml里。记下本次生成的密钥ID,或者用这个命令查看,

gpg --list-keys

image-j2ad.png
将公钥上传到公钥服务器,将YOUR_KEY_ID替换为您在第2步中生成的密钥ID,就是上面的生成结果里pub下长的那一串hash值

gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID

通过下面的命令行,可以校验公钥的字符串发往服务器是否成功。


gpg --keyserver keyserver.ubuntu.com --recv-keys YOUR_KEY_ID

maven配置修改

修改settings.xml

<settings>
  <servers>
    <server>
      <id>central</id>
      <username>token-username</username>
      <password>token-password</password>
    </server>
  </servers>
<profiles>
  <profile>
    <id>central</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <gpg.executable>gpg</gpg.executable>
      <gpg.keyname>YOUR_KEY_ID</gpg.keyname>
      <gpg.passphrase>YOUR_KEY_phrase</gpg.passphrase>
    </properties>
  </profile>
</profiles>
</settings>

项目 pom 修改

  <developers>
        <developer>
            <name>wanghao</name>
            <email>helloworldwh@163.com</email>
            <url>https://github.com/forget-the-bright</url>
        </developer>
    </developers>

    <licenses>
        <license>
            <name>The Apache Software License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
            <distribution>repo</distribution>
            <comments>The Apache Software License, Version 2.0</comments>
        </license>
    </licenses>

    <scm>
        <connection>scm:git:https://github.com/forget-the-bright/HaoUtil.git</connection>
        <developerConnection>scm:git:https://github.com/forget-the-bright/HaoUtil.git</developerConnection>
        <url>https://github.com/forget-the-bright/HaoUtil.git</url>
    </scm>

    <distributionManagement>
        <snapshotRepository>
            <id>central</id>
            <url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
        </snapshotRepository>
        <repository>
            <id>central</id>
            <url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
        </repository>
    </distributionManagement>


<build>
        <plugins>
            <!--spring-boot-maven-plugin 如果不是springboot starter 项目可以不加 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                    <!-- 不设置skip为false:打包的时候生成的jar包结构如下:BOOT-INF下包括了项目结构包和lib(依赖的代码jar包),
                    最外层还有一个启动加载器类包,主要用在需求执行(运行)的jar,如果打包是一个依赖包,不需要单独运行,
                    就设置 <skip>true</skip>.如果是一个需要启动运行的jar,就不需要添加<skip>,或者设置<skip>为false。
                     -->
                    <skip>true</skip>
                </configuration>

            </plugin>


            <plugin>
                <groupId>org.sonatype.central</groupId>
                <artifactId>central-publishing-maven-plugin</artifactId>
                <version>0.4.0</version>
                <extensions>true</extensions>
                <configuration>
                    <publishingServerId>central</publishingServerId>
                    <tokenAuth>true</tokenAuth>
                    <autoPublish>true</autoPublish>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-gpg-plugin</artifactId>
                <version>1.5</version>
                <executions>
                    <execution>
                        <id>sign-artifacts</id>
                        <phase>verify</phase>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                        <configuration>
                            <keyname>${gpg.keyname}</keyname>

                        </configuration>

                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.2.1</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar-no-fork</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <version>2.9.1</version>
                <executions>
                    <execution>
                        <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>


        </plugins>
    </build>

发布中央仓库

项目目录下面执行

mvn clean install deploy

本地命令执行成功

可以到这个网址看publish 情况
可能会显示你的版本“PUBLISHING”,时间不应超过几分钟。单击“REFRESG”按钮可查看最新过程的状态。如果您的组件不满足所有要求,您的部署将失败,部署卡的右侧列(标记为“验证结果”)将详细说明哪些验证失败。

发布成功

发布成功后,可以到官方仓库首页搜索你的项目名字试试:
Maven Central

注意事项

  1. javadoc 生成文档报错 一般都是classpath 的问题,将classpath 里面的 %JAVA_HOME% 替换为真实的 java路径即可
  2. javadoc 生成文档报错 生成提示java文件报错,如果Java文件中的注释里面有@符号,去掉即可。
  3. 如果报400错误,很有可能是你已经上传过的jar,同一个版本再次重复上传了。
  4. 如果maven depoly发布命令报401 authentication错误,是因为你的maven的setting.xml的server配置的用户名密码错误
  5. 项目里面的groupId 要和 中央仓库的名称空间保持一值
  6. 版本号不能含有SNAPSHOT 必须是1.0.0 或者其他1.0.0-REALEASE 其他符合,SNAPSHOT快照这样的不能使用
  7. 版本号已经上传成功的无法再次上传,中央仓库比较严格,已经上传成功的也无法撤回或者删除,只能上次新版本。通知用户使用新版本

CLOSE&RELEASE

项目jar正确的上传到nexus repository仓库之后,我们还需要进行进一步的操作。这是因为我们上传的jar放入了staging暂存库里面,我们需要把它转到release库,这其中sonatype平台会针对你的项目信息、jar文档、源码等内容进行完整性校验,完整性校验不通过的项目是无法转到release的,也就无法同步到maven中央仓库。

这些操作需要我们通过界面进行,使用sonatype注册用户进行登录:https://s01.oss.sonatype.org/ 。如图所示,如果我们项目打包上传成功,会在Staging Repository里面看到一个Repository,将其勾选。点击“CLOSE”按钮之后,会自动进行完整性校验,校验结果可以双击勾选仓库所在行进行查看。(只要按照我上文中的内容,将pom中的项目信息以及打包配置填写完整,这里基本都会校验通过)

CLOSE校验通过之后,刷新几次页面,Release按钮就变成可点击的状态。此时点击Release按钮,就将项目jar从Staging暂存库,转移到了Release正式库。实际上需要我们操作的内容就全都完成了。

sonatype maven库的项目会自动同步到maven中央仓库,通过maven坐标引入使用即可,不要着急,这个过程可能会有一些延时。上传之后可能一段时间内无法在maven中央仓库搜索到,但是使用maven坐标下载jar包也没有问题。