加个依赖就生效?一行搞定 Spring Boot Starter 自动装配

作者:苏渡苇

项目地址github.com/iweidujiang...(感谢 Star !)

一、加完依赖,谁帮你 new 的那些 Bean?

写 Spring Boot 的人都干过这种事:

xml 复制代码
<dependency>
  <groupId>io.github.iweidujiang</groupId>
  <artifactId>spring-insight-agent-starter</artifactId>
  <version>0.1.0-SNAPSHOT</version>
</dependency>

然后 application.yml 里丢两行:

yaml 复制代码
spring:
  application:
    name: my-service
  insight:
    server-url: http://localhost:9966

启动应用,日志里冒出一句:

text 复制代码
[AgentStarter] Spring Insight Agent 已启用......

你自己的启动类上没写 @EnableSpringInsight,也没扫 io.github.iweidujiang 这个包。那些拦截器、上报器、配置类是怎么进容器的?

很多人会下意识猜:

大概 Spring 把第三方 jar 里的类全扫了一遍吧?

不是。要真这么干,classpath 上每个库的 @Configuration 都会往你应用里塞 Bean,那才叫灾难。

真正的机关,就藏在 Starter 里一个不怎么起眼的文本文件

二、并非靠"组件扫描",而是"自动装配"

Spring 默认只扫你启动类所在包及其子包

你的服务是 com.example.order.OrderApplication,Insight 的类在 io.github.iweidujiang.springinsight......。两边包名八竿子打不着,@SpringBootApplication 扫不到它们,这是故意的。

所以 加个 Starter 就能用,靠的不是扫描,靠的是 自动装配清单:Starter 自己报名------「启动的时候请把我这个配置类加载进去」。

Spring Boot 3 认的清单文件名有点长,但路径是固定的:

text 复制代码
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Spring Insight 的业务侧 Starter 里,这个文件现在就两行:

text 复制代码
io.github.iweidujiang.springinsight.agent.starter.InsightAgentAutoConfiguration
io.github.iweidujiang.springinsight.feign.InsightFeignTracingAutoConfiguration

没有 XML,没有魔法注解扫描全世界。就是全限定类名,一行一个

你可以把它想成饭店后厨的「今日出餐表」:不是把仓库里所有菜都端上桌,只做表上写了的那几道。

三、Boot 启动时到底读了什么

流程其实很土,土到你用 jar tf 就能验证:

text 复制代码
你的应用启动
    → Spring Boot 把依赖 jar 翻一遍
    → 找到所有 AutoConfiguration.imports
    → 按里面的类名把配置类注册进容器
    → 每个配置类上的 @ConditionalXxx 再决定:这次要不要真的生效

几点容易混:

1. 这不是老的 spring.factories

Boot 2.7 之前,自动配置写在:

text 复制代码
META-INF/spring.factories

键是 org.springframework.boot.autoconfigure.EnableAutoConfiguration

Boot 3 把自动配置清单拆成了上面那个 .imports 文件。

Insight 的 insight-agent还有 一个 spring.factories,但那是给 EnvironmentPostProcessor 用的,跟「报名 AutoConfiguration」不是一回事。

2. 清单要放在 Starter 里,别放在纯库里

insight-agent 是采集核心,谁依赖它谁都能用它的类;但报名自动装配的是 spring-insight-agent-starter

这是 Starter 的老规矩:库本身尽量「老实」,不要因为被人间接依赖就自己往容器里塞东西。业务方显式加 Starter,才表示「我同意你自动起来」。

3. 报了名,不等于一定干活

清单只解决「配置类进不进容器」。进了之后,还要过 @ConditionalOnProperty@ConditionalOnClass 这些关。关过不了,配置类就躺着,不捣乱。

四、对照 Spring Insight 的入口类

第一行对应的类长这样:

java 复制代码
@AutoConfiguration
@EnableConfigurationProperties(InsightProperties.class)
@ConditionalOnProperty(
        prefix = "spring.insight",
        name = "enabled",
        havingValue = "true",
        matchIfMissing = true)
@Import(InsightAgentAutoConfigurationImportSelector.class)
public class InsightAgentAutoConfiguration {

    public InsightAgentAutoConfiguration() {
        log.info("[AgentStarter] Spring Insight Agent 已启用......");
    }
}

四个注解各管一件事:

注解 人话
@AutoConfiguration 告诉 Boot:我是自动配置,按自动配置的规则排序、加载
@EnableConfigurationProperties spring.insight.* 绑到 InsightProperties
@ConditionalOnProperty 开关。enabled=true 才干;没配也当 truematchIfMissing = true
@Import(...) 真正的拦截器、上报器不堆在这一个类里,交给选择器按 Web 栈再导入

最后那个 @Import 是下一篇的主角。本篇内容主要是自动装配:自动装配的门,是 .imports 文件推开的;门后面装什么,是这个配置类接着干的。

构造方法里打那行 info 日志,也是有用的土办法------Starter 这种「看不见的依赖」,最怕静悄悄失败。启动后搜 [AgentStarter],比猜「到底装上没有」省事。

五、为什么还要第二行:Feign 那个配置

.imports 里第二行是 InsightFeignTracingAutoConfiguration。它上面挂了:

java 复制代码
@AutoConfiguration
@ConditionalOnWebApplication(type = SERVLET)
@ConditionalOnClass(Client.class)  // feign.Client
public class InsightFeignTracingAutoConfiguration { ... }

翻译成人话:

  • 你这个服务没有 OpenFeign → feign.Client 不在 classpath → 这个配置直接跳过,零影响
  • 你是普通 MVC 服务, Feign → 才去给 Feign Client 套一层,方便后面画拓扑

Starter 的 pom 里,feign-coreoptional。自动装配清单里把 Feign 单独挂一行,就是为了:有就用,没有就当这段代码不存在。

别把所有能力塞进一个巨型 @Configuration。条件越细,别人项目越不容易被你拖进坑里。

六、怎么确认它真的生效了(以及怎么关掉)

看日志。 启动后搜:

text 复制代码
[AgentStarter] Spring Insight Agent 已启用

没有这行,先查三件事:依赖是不是 agent-starter 、是不是 Boot 3(.imports 这套)、jar 里到底有没有那个 META-INF/spring/...imports 文件。

看开关。 不想要了,不必删依赖,配一行就行:

yaml 复制代码
spring:
  insight:
    enabled: false

matchIfMissing = true 的意思是:你懒得配,默认开;你明确说 false,就关。这比再搞一个「必须写 @EnableXxx 才启动」对使用者更友好。

看它不会替你做的事。 自动装配只保证「Bean 进容器」。数据往哪报、服务叫什么,还是配置说了算:

  • 没配 spring.insight.server-url,HTTP 上报 Sink 根本不会建出来
  • 没起 insight-server,报了也没人收
  • 拓扑边还依赖 Feign 那层包装(有 Feign 才会走第二行配置)

「加依赖就生效」≠「加依赖就万事大吉」。生效的是装配,不是整个监测系统自己长出来。

七、自己做 Starter

如果哪天你也有需要做个 Starter,无需一上来就写 ImportSelector、别一上来就研究 AutoConfiguration 排序。做好如下三步即可:

  1. 单独一个 xxx-spring-boot-starter 模块,不要让业务直接依赖你的核心 jar 然后指望它自动起来
  2. 在 Starter 里放 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,一行一个配置类
  3. 配置类上用 @ConditionalOnProperty / @ConditionalOnClass 把「没有的能力」挡在门外,再留一个默认开、能关掉的开关

Insight 现在就是这个形状。

八、小结

你以为的 实际是
扫描了第三方包 只扫你自己的启动类包
某个注解偷偷全局生效 .imports 文件点名加载配置类
加了 Starter 就等于功能全开 还要过 @Conditional*,还要配 server-url
必须写 @EnableXxx 有 Starter 时,注解是可选项

Spring Boot 的「约定大于配置」,落到 Starter 上就一句大白话:你把全限定类名写进那个文件,Boot 启动时会来读。

下一篇会接着讲 后面的 @Import:为什么 Gateway 上不能把 MVC 的 HandlerInterceptor 硬塞进去,以及 DeferredImportSelector 在 Insight 里具体干了啥。

🌟 最后:欢迎围观 Spring Insight

如果你对「轻量监测 / Spring Boot Starter / 链路埋点」感兴趣,欢迎看看这个还在打磨的小项目:

🔗 GitHubgithub.com/iweidujiang...

当前形态很朴素:业务服务加 spring-insight-agent-starter,旁边单独跑 insight-server 看拓扑和链路。能力有限,代码也还糙,适合当练手和对照。

你的 Star 是对我最大的鼓励。

相关推荐
月华路1 小时前
G1 新生代对象晋升老年代:实现机制与 GC 日志
java·jvm·算法
AI人工智能+电脑小能手1 小时前
大白话说Java设计模式-34-命令模式(业务实战篇)
java·spring·设计模式·命令模式·异步任务·撤销重做·事务封装
净重21克1 小时前
万字长文!TLS协议升级避坑手册:JDK老项目适配TLS1.2/1.3全流程拆解
java·springboot·java安全
一直C1 小时前
【数据结构】哈希表+算法复杂度与经典排序查找(C语言)
java·linux·开发语言·数据结构·算法·ubuntu·散列表
paopaokaka_luck1 小时前
基于springboot3+vue3的车间生产管理系统(Echarts图形化分析、BI报表)
java·前端·spring boot·学习·echarts
程序员鱼皮2 小时前
3 大 DeepSeek Harness 进阶玩法,招多个大肥鱼帮我干活!
前端·后端·ai编程
苍何2 小时前
DeepSeek 终于支持多模态了(附实测及接入教程)
后端
KoPa2 小时前
HeySmart:大模型开源网关基座-请求生命周期与钩子引擎
前端·后端
苍何2 小时前
做AI视频还在拆盲盒?手把手教你导演级运镜(附教程)
后端