本篇主要讲述 Spring Boot Starter 的概念、命名规范,以及如何自定义一个 Starter,下面开始今天的内容。

springboot文件夹命名 springboot命名规范_spring boot

1 Starter 是什么

Spring Boot 的 Starter 是一组比较方便的依赖描述符,可以通过 Maven 将其打成jar包,并在你的项目中直接引用。

通过 Starter 你可以获取该功能的所有依赖,以及统一的配置,避免了复制、粘贴代码和依赖带来的麻烦。

Starter 主要使用了自动配置,所以它下面的所有组件会被 Spring Boot 通过META-INF/spring.factories文件注入IOC容器中。

2 命名规范

2.1 Starter 项目的命名规范

所有由Spring官方提供的Starter都会遵循spring-boot-starter-*的命名规范,其中*表示特定类型的应用程序。

而所有第三方的Starter,官方建议以项目名称开头,应遵循*-spring-boot-starter的命名规范,其中*表示第三方项目名称。

2.2 配置项的命名规范

如果自定义的 Starter 包含了配置项,请为它使用唯一的命名空间,不要与 Spring Boot 或其他组件产生冲突,例如:servermanagementspring

3 自定义一个 Starter

一个典型的 Starter 包含自动配置和自定义的核心代码。为了演示方便,本例中的核心代码就是一个“宠物”类,能够根据配置的“类型”来获取对应的“宠物”,下面看具体实现过程。

3.1 创建自定义的 Starter 工程

创建一个 Spring Boot 工程,将其命名为demo-spring-boot-starter。下图是工程完整目录结构,后面会逐一介绍它们。

springboot文件夹命名 springboot命名规范_spring boot_02

3.2 POM中引入相关依赖

在POM中引入两个依赖:

  • spring-boot-starter:该依赖是 Starter 的核心,包括自动配置、日志和YAML的支持。我们所有自定义的 Starter 都应该直接或间接的引入该依赖。
  • spring-boot-configuration-processor:包含一个 Java 注解处理器,当使用@ConfigurationProperties注解配置自己的元数据时,需要引入此依赖。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

3.3 定义一个配置元数据类

自定义一个配置元数据类DemoProperties,用于映射YAML中的配置,使用@ConfigurationProperties注解需要指定配置项的前缀,此处的前缀为demo。当前配置项只有一个type字段,用于配置宠物的类型,那么该配置项的 Key 为:demo.type

@ConfigurationProperties(prefix = "demo")
public class DemoProperties {

    /**
     * 类型
     */
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

3.4 定义一个配置类

先看自定义的宠物实体类Pet,很简单,只有一个name属性(此类纯属为了演示 Starter,无它)。

public class Pet {

    /**
     * 名称
     */
    private String name;

    public Pet(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

增一个配置类DemoAutoConfiguration,该类也非常简单:

  • 使用@Configuration注解声明该类为一个配置类;
  • 使用@EnableConfigurationProperties注解,引入自定义的配置元数据DemoProperties
  • 声明了一个Pet的 Bean,根据配置项中的type来返回不同的宠物。使用该 Bean 的目的,主要是用来演示 Starter 的自动配置。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(DemoProperties.class)
public class DemoAutoConfiguration {

    private final DemoProperties demoProperties;

    public DemoAutoConfiguration(DemoProperties demoProperties) {
        this.demoProperties = demoProperties;
    }

    @Bean
    public Pet pet() {
        if (!StringUtils.hasText(demoProperties.getType())) {
            return new Pet("空的");
        }
        switch (demoProperties.getType()) {
            case "cat":
                return new Pet("小猫");
            case "dog":
                return new Pet("小狗");
            default:
                return new Pet("未知");
        }
    }
}

3.5 定义自动配置的候选

resources资源目录中增加文件META-INF/spring.factories,并将自定义的配置类DemoAutoConfiguration加入到自动配置类列表中,如下代码:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.github.gozhuyinglong.autoconfigure.DemoAutoConfiguration

这一步比较关键,需要重点说一下。

我们自定义Starter 的相关组件,肯定不在使用者自动扫描的目标中(目录结构不同),所以 Spring Boot 提供了这种机制,能够使第三方使用者发现这些组件。

Spring Boot 会检查所有发布的jar中是否包含META-INF/spring.factories文件,并将该文件中目标类注入IOC容器中,自动配置类就是使用这种方式加载的。

 

4 使用 Starter

我们再次创建一个工程,用于测试 Starter 是否生效。注意该工程的目录结构要与 Starter 的目录结构不同,这样才能测试出 Starter 中的组件是被 META-INF/spring.factories文件引入的,而非自动扫描。

4.1 创建一个客户端工程

创建一个 Spring Boot 工程,将其命名为 demo-client。下图是工程完整目录结构,后面会逐一介绍它们。

springboot文件夹命名 springboot命名规范_java_03

4.2 引入自定义 Starter 依赖

在POM文件中,引入刚者自定义的 Starter 依赖。为了便于测试,将spring-boot-starter-web也引入进来。

<dependency>
    <groupId>io.github.gozhuyinglong</groupId>
    <artifactId>demo-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

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

4.3 创建启动类

创建主启动类ClientApplication,注意该类的目录与 Starter 不同,也就是说当前工程不会通过@ComponentScan方式自动扫描 Starter 中的组件。

@SpringBootApplication
public class ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }
}

4.4 配置“宠物”的类型

自定义的 Starter 中可以配置宠物的类型,将其配置为dog

demo:
  type: dog

4.5 创建一个 Controller 类

创建一个ClientController类,用于测试 Starter 是否生效

@RestController
@RequestMapping("/client")
public class ClientController {

    @Autowired
    private Pet pet;

    @GetMapping("/test")
    public String test() {
        return pet.getName();
    }
}

4.6 测试 Starter

启动项目后,使用 Postman 或直接在浏览器中输入地址:http://127.0.0.1:8080/client/test,会发现输出了“小狗”,表示成功。

springboot文件夹命名 springboot命名规范_spring boot_04