一、什么是SpringBoot starter机制

SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂的配置,将其统一集成进starter,

应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。

starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,

并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。

所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。

二、为什么要自定义starter ?

在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,

然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。

如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可,

SpringBoot为我们完成自动装配,简直不要太爽

三、什么时候需要创建自定义starter?

在我们的日常开发工作中,可能会需要开发一个通用模块,以供其它工程复用。SpringBoot就为我们提供这样的功能机制,

我们可以把我们的通用模块封装成一个个starter,这样其它工程复用的时候只需要在pom中引用依赖即可,

由SpringBoot为我们完成自动装配。

四、自定义starter的开发流程(案例:为短信发送功能创建一个starter)

创建Starter项目

starter项目和SpringBoot工程结构没有什么区别

1、细节:命名规范

SpringBoot官方命名方式

格式:spring-boot-starter-{模块名}

举例:spring-boot-starter-web

自定义命名方式

格式:{模块名}-spring-boot-starter

pom依赖,打包时需要注意一下,SpringBoot项目打包的JAR是可执行JAR,它的类放在BOOT-INF目录下,如果直接作为其他项目的依赖,会找不到类。可以通过修改如下代码最后面一段解决

<?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>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.6</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.example</groupId>
  <artifactId>demo-spring-boot-starter</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>demo-spring-boot-starter</name>
  <description>demo-spring-boot-starter</description>
  <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-configuration-processor</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </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>

创建一个配置文件类DemoProperties.java 

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

  private String name;
  private String value;

  public String getName() {
    return name;
  }

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

  public String getValue() {
    return value;
  }

  public DemoProperties setValue(String value) {
    this.value = value;
    return this;
  }
}

创建一个核心业务类DemoService.java

public class DemoService {

  private String name;
  private String value;

  public DemoService(String name, String value) {
    this.name = name;
    this.value = value;
    System.out.println("DemoService init success!");
  }

  public String getName() {
    return name;
  }

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

  public String getValue() {
    return value;
  }

  public DemoService setValue(String value) {
    this.value = value;
    return this;
  }

  public void say() {
    System.out.println(name + " say: " + value);
  }

创建一个配置类DemoAutoConfiguration.java

@Configuration
// 引入配置文件类
@EnableConfigurationProperties(DemoProperties.class)
// 只有在配置了demo的配置信息时,才进行加载
@ConditionalOnProperty(prefix = "demo", value = "name")
public class DemoAutoConfiguration {

  @Autowired
  private DemoProperties properties;

  @Bean
  public DemoService demoService() {
    return new DemoService(properties.getName(), properties.getValue());
  }
}

在/resources/META-INF/目录下添加spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autoconfiguration.configuration.DemoAutoConfiguration

整体项目结构为:

spring validation 自定义 spring自定义starter_maven

执行 mvn clean install -Dskiptests 打包命令。

验证starter

我们随便创建一个SpringBoot项目,引入我们定义的starter

spring validation 自定义 spring自定义starter_maven_02

在配置文件application.properties中添加配置

demo.name=joey
demo.value=hello

编写测试类

@SpringBootTest
class TestApplicationTests {

  @Resource
  private DemoService demoService;

  @Test
  void test() {
    demoService.say();
  }

}

编写测试类

spring validation 自定义 spring自定义starter_spring_03

这就是一个简单的自定义starter

总结

  1. 自定义starter命名规范:xxx-spring-boot-starter
  2. starter组成为 一个starter包(负责引入依赖),一个autoconfiguration包(负责实现装配)
  3. autoconfiguration包定义对应的properties类,configuration类,核心业务类。
  4. autoconfiguration包的/resources/META-INF/目录下添加spring.factories文件,并配置org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.qiejk.demo.springboot.autoconfiguration.DemoAutoConfiguration,这步是SpringBoot装配的核心,只有添加了这个内容,SpringBoot才会进行自动装配。