SpringBoot创建自定义starter指北 - ZhangTory's NoteBlog - 张耀誉的笔记博客

SpringBoot创建自定义starter指北

之前我们解了SpringBoot自动配置原理,根据原理我们就可以实现我们自己的starter。
为什么需要starter,官方文档写的很不错。

If you work in a company that develops shared libraries, or if you work on an open-source or commercial library, you might want to develop your own auto-configuration. Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.
如果您在开发共享库的公司工作,或者在开源或商业库上工作,您可能需要开发自己的自动配置。自动配置类可以绑定在外部jar中,仍然可以由springboot获取。

在我百度了很多博文后,发现很多文章都不太让我满意,最终查询了官方文档,在这里:官方文档地址
强烈建议看看官方文档,在动手创建starter项目之前,先理解一些前置知识。

创建maven父工程

首先我们需要按照官方的约定创建工程。
典型的Spring Boot starter包含自动配置代码和特定业务代码。
官方建议将autoconfigure 和starter拆分为2个工程。
当然这并不是必要的,如果是很简单的项目,那么可以合并为1个。
网上很多文章都是合并到1个中,因为只是demo,比较简单。
本次我将拆分为2个工程,按照官方的规范执行。

关于项目命名规范,自定义的starter必须以xxx-spring-boot-starter命名,以区分自定义starter和官方starter。
本次以hello-spring-boot为例,如果拆分为2个工程,那么应该分别命名为hello-spring-boot-autoconfigurehello-spring-boot-starter
如果只有1个工程,那么直接命名为hello-spring-boot-starter

所以我们先创建一个maven父工程,名为hello-spring-boot
pom中只保留目工程的GAV坐标就行了。
后续创建了2个module,最终pom如下:

<?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.zhangtory</groupId>
  <artifactId>hello-spring-boot</artifactId>
  <packaging>pom</packaging>
  <version>1.0</version>

  <modules>
      <module>hello-spring-boot-starter</module>
      <module>hello-spring-boot-autoconfigure</module>
  </modules>

</project>

创建自动配置业务功能实现的工程

使用Spring Initializr创建一个SpringBoot工程,中间可以加入需要的依赖。
根据规范要求,这个项目应该命名为hello-spring-boot-autoconfigure

根据我们之前了解的自动配置原理,创建好工程后一共需要3步走。
1.编写配置的业务代码。
2.创建自动配置类。
3.创建spring.factories文件。

0. 修改pom

创建好后,首先需要修改pom,移除开头spring-boot-starter-parent的<parent>。
然后加入

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

如果不移除开头的spring-boot-starter-parent,那么后续使用时,不能导入需要的类文件,会提示找不到包。
加入spring-boot-dependencies的dependencyManagement是因为创建自动配置类的注解需要。
整个pom如下:

<?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>com.zhangtory</groupId>
    <artifactId>hello-spring-boot-autoconfigure</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello-spring-boot-autoconfigure</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</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>
    </dependencies>

     <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

</project>

1. 编写配置的业务代码。

实现业务代码功能HelloService:

public class HelloService {
    
    public void print(String str) {
        System.out.println("hello, " + str);
    }

}

2. 创建自动配置类。

创建自动配置类HelloAutoConfiguration:

@Configuration
public class HelloAutoConfiguration {

    @Bean
    @ConditionalOnClass(HelloService.class)
    @ConditionalOnMissingBean
    public HelloService helloService() {
        return new HelloService();
    }

}

这几个注解大家应该都知道,@ConditionalOnClass(HelloService.class)要求存在HelloService这个class文件时执行,@ConditionalOnMissingBean表示当spring中没有helloService这个bean时执行。

3. 创建spring.factories文件。

首先在resources下创建META-INF文件夹,然后再创建spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zhangtory.hellospringboot.HelloAutoConfiguration

创建hello-spring-boot-starter

直接创建一个空maven项目就可以了。
修改pom文件,保留GAV坐标,并引入hello-spring-boo-autoconfiguret

<?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.zhangtory</groupId>
    <artifactId>hello-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.zhangtory</groupId>
            <artifactId>hello-spring-boot-autoconfigure</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

使用自定义starter

首先在maven父工程中执行install命令。
然后在其他项目中引入maven坐标即可。

<dependency>
    <groupId>com.zhangtory</groupId>
    <artifactId>hello-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

在代码中如果需要使用对应的业务类,直接Autowired就行了。

    @Autowired
    private HelloService helloService;

添加新评论

电子邮件地址不会被公开,评论内容可能需要管理员审核后显示。