bigywater.tech
Spring · 67

自己写一个 starter

怎么自己写一个 starter?配置提示是怎么来的?为什么我的自动配置没有生效也不报错?可选依赖怎么处理才不会在没有它的项目里炸?这篇真的写了一个库、打成 jar,放进使用方应用里逐个验证。

0 个报错
库里漏写 AutoConfiguration.imports 时,GreetingService 不存在,但没有任何错误信息
ClassNotFoundException
方法级 @ConditionalOnClass 保护不了返回类型就是可选类的 @Bean 方法
3
configuration-processor 生成的元数据里的属性个数,说明文字取自 Javadoc

元数据

实测 · 本机执行输出
  META-INF/spring-configuration-metadata.json 里的属性:
    greeting.enabled  类型 java.lang.Boolean  默认值 True  说明「是否启用问候服务。」
    greeting.prefix  类型 java.lang.String  默认值 Hello  说明「问候前缀。」
    greeting.suffix  类型 java.lang.String  默认值 !  说明「问候后缀。」

类路径上有 configuration-processor,编译就会生成元数据文件。

零配置

实测 · 本机执行输出
  库 jar(带 imports 文件):
    GreetingService Bean = [greetingService],greet("Tom") = Hello, Tom!,GreetingDecorator Bean = []
  greeting.prefix=Hi、greeting.suffix=?:
    GreetingService Bean = [greetingService],greet("Tom") = Hi, Tom?,GreetingDecorator Bean = []
  greeting.enabled=false:
    GreetingService Bean = [],GreetingDecorator Bean = []
  使用方自己定义了 GreetingService(user.service=true):
    GreetingService Bean = [myService],greet("Tom") = 用户自己的 GreetingService 说:Tom,GreetingDecorator Bean = []

放进 classpath 即生效,属性可覆盖,用户 Bean 让路。

imports 文件

实测 · 本机执行输出
  库 jar(没有 imports 文件):
    GreetingService Bean = [],GreetingDecorator Bean = []

漏写不会报错,自动配置静默失效。

可选依赖

实测 · 本机执行输出
  类路径上没有 optlib:
    GreetingService Bean = [greetingService],greet("Tom") = Hello, Tom!,GreetingDecorator Bean = []
  类路径上有 optlib:
    GreetingService Bean = [greetingService],greet("Tom") = ✨Hello, Tom!✨,GreetingDecorator Bean = [fancyDecorator]

用类级别条件单独保护,主体不引用可选类。

陷阱

实测 · 本机执行输出
  库 jar(BadAutoConfiguration 已列入 imports),类路径上没有 optlib:
    启动失败:BeanCreationException ← … ← ClassNotFoundException: optlib.FancyFormatter
  同一个库 jar,类路径上有 optlib:
    GreetingService Bean = [greetingService],greet("Tom") = ✨Hello, Tom!✨,GreetingDecorator Bean = [fancyDecorator]

方法级 @ConditionalOnClass 保护不了方法签名里的类。

分步演示

自己写一个 starter
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动。库源码用 javac 编译(类路径上有 spring-boot-configuration-processor),手工打成 jar(good 版有 imports 文件,noimports 版没有,bad 版多列了 BadAutoConfiguration);使用方应用是同一份启动代码,换 classpath 分别运行;optlib 是另一个单独编译的 jar
    • 没有验证:命名约定(xxx-spring-boot-starter 与 xxx-spring-boot-autoconfigure 分成两个模块)带来的好处;additional-spring-configuration-metadata.json 的手写补充;@ConfigurationProperties 的校验与构造器绑定在库里的写法(见第 71 篇);给自动配置写测试用的 ApplicationContextRunner;发布到 Maven 仓库后的版本管理
    京ICP备2026067502号-1京公网安备11010502063487号