下面以创建一个 自定义 Greeting Starter 为例,完整演示如何从零编写一个 Spring Boot Starter。
整体结构
bash
greeting-spring-boot-starter/
├── pom.xml
└── src/main/
├── java/com/example/greeting/
│ ├── GreetingProperties.java ← 配置属性类
│ ├── GreetingService.java ← 核心服务类
│ └── GreetingAutoConfiguration.java ← 自动配置类
└── resources/
└── META-INF/
└── spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports ← 注册自动配置类
第一步:pom.xml
xml
<project>
<groupId>com.example</groupId>
<artifactId>greeting-spring-boot-starter</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<!-- 自动配置的核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
第二步:配置属性类
定义可以在 application.properties 中配置的属性:
typescript
package com.example.greeting;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "greeting")
public class GreetingProperties {
/**
* 问候前缀,默认值 "Hello"
* 对应配置:greeting.prefix=Hello
*/
private String prefix = "Hello";
/**
* 问候后缀,默认值 "!"
* 对应配置:greeting.suffix=!
*/
private String suffix = "!";
public String getPrefix() { return prefix; }
public void setPrefix(String prefix) { this.prefix = prefix; }
public String getSuffix() { return suffix; }
public void setSuffix(String suffix) { this.suffix = suffix; }
}
第三步:核心服务类
这是 Starter 真正要提供的功能:
arduino
package com.example.greeting;
public class GreetingService {
private final GreetingProperties properties;
public GreetingService(GreetingProperties properties) {
this.properties = properties;
}
public String greet(String name) {
return properties.getPrefix() + " " + name + properties.getSuffix();
}
}
第四步:自动配置类
这是 Starter 的灵魂------告诉 Spring Boot "在什么条件下自动注册哪些 Bean":
kotlin
package com.example.greeting;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
@EnableConfigurationProperties(GreetingProperties.class) // 激活属性绑定
public class GreetingAutoConfiguration {
@Bean
@ConditionalOnMissingBean // 如果用户自己定义了 GreetingService,就不自动创建
public GreetingService greetingService(GreetingProperties properties) {
return new GreetingService(properties);
}
}
常用条件注解说明:
| 注解 | 含义 |
|---|---|
@ConditionalOnClass |
classpath 中有某个类时才生效 |
@ConditionalOnMissingBean |
容器中没有某个 Bean 时才创建 |
@ConditionalOnProperty |
配置文件中某个属性满足条件时才生效 |
@ConditionalOnMissingClass |
classpath 中没有某个类时才生效 |
第五步:注册自动配置类
Spring Boot 2.7+(推荐方式)
创建文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
内容只有一行:
com.example.greeting.GreetingAutoConfiguration
Spring Boot 2.7 以下(旧方式)
创建文件:META-INF/spring.factories
ini
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.greeting.GreetingAutoConfiguration
第六步:打包发布
mvn clean install
这会将 Starter 安装到本地 Maven 仓库。
第七步:在其他项目中使用
引入依赖
xml
<dependency>
<groupId>com.example</groupId>
<artifactId>greeting-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
可选:自定义配置
ini
# application.properties
greeting.prefix=你好
greeting.suffix=,欢迎!
直接注入使用
less
@RestController
public class HelloController {
@Autowired
private GreetingService greetingService;
@GetMapping("/hello")
public String hello(@RequestParam String name) {
return greetingService.greet(name);
// 默认返回:Hello 张三!
// 配置后返回:你好 张三,欢迎!
}
}
整体流程总结
java
用户引入 starter jar
↓
Spring Boot 扫描 META-INF 下的注册文件
↓
发现 GreetingAutoConfiguration
↓
@ConditionalOnMissingBean 检查容器中是否已有该 Bean
↓
没有 → 自动创建 GreetingService 并注册到容器
↓
用户通过 @Autowired 直接使用,零配置开箱即用
核心思想:Starter 的本质就是"自动配置 + 条件装配"------把常用的 Bean 创建逻辑封装好,用户引入 jar 包后自动生效,想定制就改配置文件,想完全接管就自己定义同类型 Bean 覆盖掉。