SpringBoot 3 进阶教程之四自定义 Starter

大纲

前言

本文主要介绍 SpringBoot 3 如何自定 Starter,完整的案例代码可以直接从 GitHub 下载对应章节 spring-boot3-09spring-boot3-10。值得一提的是,下述教程适用于 SpringBoot 2.x 和 SpringBoot 3.x。

自定义 Starter

自定义场景

  • 使用场景:抽取聊天机器人场景,它可以打招呼
  • 最终效果:任何项目导入此 Starter 都具有打招呼功能,并且问候语中的人名支持在配置文件中修改

自定义步骤

  • 1、创建自定义 Starter 模块,引入 spring-boot-starter 基础依赖
  • 2、开发模块功能,引入模块所有需要的依赖
  • 3、创建 XxxAutoConfiguration 自动配置类,帮其他项目导入使用这个模块所需要的全部组件
  • 4、为其他项目引入 XxxAutoConfiguration 自动配置类
    • 第一种方式: 创建 @EnableXxx 注解类,使用 @Import(XxxAutoConfiguration.class) 注解引入自定义配置类
    • 第二种方式: 创建 SPI 配置文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,指定应用启动时需要加载的自动配置类
  • 5、其他项目引入自定义的 Starter 即可使用对应的功能

自定义案例

开发业务逻辑代码

  • 创建配置属性类,绑定 YML 或者 Properties 配置文件中指定前缀的内容
1
2
3
4
5
6
7
8
9
@Data
@ConfigurationProperties(prefix = "robot")
public class RobotProperties {

private String name;

private String email;

}
  • 创建控制器和服务类,模拟自定义 Starter 提供的业务功能
1
2
3
4
5
6
7
8
9
10
11
@Service
public class RobotService {

@Autowired
private RobotProperties robotProperties;

public String sayHello() {
return "Hello " + robotProperties.getName();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
@RequestMapping("/robot")
public class RobotController {

@Autowired
private RobotService robotService;

@GetMapping("/saveHello")
public String sayHello() {
return robotService.sayHello();
}

}
  • 创建自动配置类,导入使用自定义 Starter 功能所需要的全部组件
1
2
3
4
5
6
@Configuration
@Import({RobotController.class, RobotService.class})
@EnableConfigurationProperties(RobotProperties.class)
public class RobotAutoConfiguration {

}

为什么自定义 Starter 模块里的组件默认不会扫描进来?

这是自定义 Starter 所在的包和引入它的项目的主程序所在的包不是父子层级关系。 因此需要创建 XxxAutoConfiguration 自动配置类,将需要用到的组件统一导入进来。

  • 引入配置处理器依赖,重启项目后,在 IDEA 里面写 YML 或者 Properties 配置文件时就会有代码提示效果
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

使用 @EnableXxx 机制实现自动配置

在自定义 Starter 模块内创建 @EnableXxx 注解类,当其他项目需要使用自定义 Starter 提供的功能,只需要简单使用 @EnableXxx 注解即可开启对应的功能。值得一提的,此方式属于 半自动配置

1
2
3
4
5
6
7
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(RobotAutoConfiguration.class)
public @interface EnableRobot {

}

使用 SpringBoot SPI 机制实现自动配置

使用 SpringBoot 提供的 SPI 机制,在自定义 Starter 模块内创建 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 配置文件,并写入自动配置类的全类名即可。当其他项目引入自定义 Starter 模块后,应用在启动时就会自动加载对应的自动配置类。值得一提的,此方式属于 完全自动配置

  • SPI 配置文件的内容
1
com.clay.boot.starter.robot.config.RobotAutoConfiguration
  • 自定义 Starter 模块的目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
├── pom.xml
└── src
└── main
├── java
│   └── com
│   └── clay
│   └── boot
│   └── starter
│   └── robot
│   ├── config
│   │   └── RobotAutoConfiguration.java
│   ├── controller
│   │   └── RobotController.java
│   ├── properties
│   │   └── RobotProperties.java
│   └── service
│   └── RobotService.java
└── resources
└── META-INF
└── spring
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports