SpringBoot制作Starter以及bean的自动装配

发布时间:2026/7/17 6:01:13

SpringBoot制作Starter以及bean的自动装配
什么是 Starter举个例子在 Spring Boot 项目中引入 spring-boot-starter-data-redis 的依赖就获得了一个全局可用的 StringRedisTemplate 类型的 bean 对象。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency从命名上就能看出来spring-boot-starter-data-redis 就是一个 starter。当然其实 spring-boot-starter-data-redis 并不是只有 StringRedisTemplate 这么一个 bean。在 starter 中可以声明多个 bean项目在启动的时候会加载需要的 bean这个就是 bean 的自动装配。在我的理解中starter 就是一个 jar 包只需要遵循 Spring 的约定大于配置的哲学根据 Spring 的规则制作 jar 包。在其他项目中引入这个 jar 包就可以直接获得 bean 对象了不需要二次配置。如何制作自己的 starter官方自己制作的 starter 的命名规范是spring-boot-starter-xxx。spring-boot-starter-webspring-boot-starter-data-redisspring-boot-starter-mail第三方制作 starter 的命名建议是xxx-spring-boot-starter跟官方命名的方向相反。mybatis-spring-boot-starter如果是自己制作的话不用管那么多规范因为蒙多想去哪就去哪。第一步创建新项目引入依赖groupIdorg.example/groupId artifactIda/artifactId version1.0-SNAPSHOT/version properties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-autoconfigure/artifactId version3.0.0/version /dependency /dependencies第二步从配置文件获取数据还是以 spring-boot-starter-data-redis 为例我们在引入 jar 包后需要在配置文件中配置 redis 的相关信息。同样的我们制作 starter 的时候也可以从配置文件中获取数据。prefix a配置文件需要以 a 为前缀。ConfigurationProperties(prefix a) public class AProperties { private String A1; private String A2; public AProperties() { } public AProperties(String a1, String a2) { A1 a1; A2 a2; } public String getA1() { return A1; } public void setA1(String a1) { A1 a1; } public String getA2() { return A2; } public void setA2(String a2) { A2 a2; } }第三步编写业务类public class AService { private AProperties aProperties; public AService(AProperties aProperties) { this.aProperties aProperties; } public void work() { System.out.println(用户名 aProperties.getA1()); System.out.println(密码 aProperties.getA2()); System.out.println(starter业务执行); } }这里简单提供了一个 work 方法打印 A1、A2 对应的取值用来模拟从配置文件中获得地址、用户名、密码、数据库等信息。第四步编写自动配置类Configuration EnableConfigurationProperties(AProperties.class) public class AAutoConfig { Bean public AService aService(AProperties aProperties) { return new AService(aProperties); } }在这个自动配置类中通过方法返回一个 bean 对象。第五步服从 Spring 的命令在 resources 目录下创建 META-INF 目录。在 META-INF 目录下创建 spring 目录。在 spring 目录下创建 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件。在这个什么 imports 文件中写入自动配置类的全类名。org.example.a.AAutoConfig这个是 Spring Boot 3 的写法还有一种写法是 Spring Boot 2.x 的但是我都没用过 2.x 的版本所以我也不知道怎么写。但是写法本身不重要也没必要研究茴香豆的茴字有多少种写法要用的时候查一下就行了。第六步打 jar 包并保存到本地仓库通过 maven 执行 install 命令将项目打成 jar 包并保存到本地仓库中。如果是用 IDEA 写 Java 的话IDEA 本身就集成了 maven就算自己安装了 maven 也会默认用 IDEA 自带的 maven仓库目录是C:\Users\admin\.m2\repository。验证 starter 是否可正常使用创建新项目引入 starter。dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId version3.0.0/version /dependency dependency groupIdorg.example/groupId artifactIda/artifactId version1.0-SNAPSHOT/version /dependency /dependenciesserver: port: 8080 a: A1: 100 A2: 200RestController public class BController { Autowired private AService aService; GetMapping(/test) public int test() { aService.work(); return 200; } }接口正常返回数据业务方法正常执行。现在我们成功制作了一个自己的 starter之后还需要用 AService 的功能直接引入使用即可可以说是开袋即食。但是我们这么大费周章结果只是给 Spring 添加了一个 bean。我们不是可以用 Component 注解声明 bean 吗那就试试吧。Component 和配置类我在 starter 中添加了一个 bean。Component public class AComponent { public void work() { System.out.println(一个小组件); } }同时把 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 的目录和文件都删除掉了确保 bean 的加载跟上文不同。重新打包这次把版本号改成 2.0-SNAPSHOT。在测试项目中注入这个新的 bean。RestController public class BController { Autowired private AService aService; Autowired private AComponent aComponent; GetMapping(/test) public int test() { aService.work(); aComponent.work(); return 200; } }现在重新启动测试项目结果服务启动失败提示缺少 bean 对象。Description: Field aComponent in org.example.b.BController required a bean of type org.example.a.AComponent that could not be found. The injection point has the following annotations: - org.springframework.beans.factory.annotation.Autowired(requiredtrue) Action: Consider defining a bean of type org.example.a.AComponent in your configuration.为什么会出现这种情况呢因为 Spring 默认只会扫描启动类所在包和子包下面的类。我们的测试项目的包是 org.example.b而 starter 项目的包是 org.example.a在测试项目中根本就没有扫描到 org.example.a 下面的类自然不会把 AComponent 注册为 bean。解决方法很简单在启动类中添加 ComponentScan(org.example.a)指定要扫描的路径即可。SpringBootApplication ComponentScan(org.example.a) public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } }现在服务启动成功了但是接口报错了响应码是 404。这个问题就出在了 ComponentScan(org.example.a) 这里因为我们指定了要扫描路径是 org.example.a所以它不会去扫描 org.example.b我写的 Controller 都没有被扫描到Controller 里面的 test 接口自然也不会开启。浏览器向一个不存在的接口发送请求当然是 404 资源不存在。所以我们需要继续修改要扫描的路径。SpringBootApplication ComponentScan({org.example.a, org.example.b}) public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } }现在再启动项目试一下这次就顺利启动并且接口正常响应了。Spring Boot 中 bean 的自动装配在我看来bean 的创建有两种方式Component 注解声明的 beanConfiguration 配置类中 Bean 方法返回的 bean一个项目中 bean 的来源有两个途径项目本身声明的 bean项目需要的依赖中引入的 bean现在两两组合一下得到了四种取值项目自己通过 Component 注解被 ComponentScan 扫描注册为 bean项目自己通过 Configuration 配置类中 Bean 注解也是被 ComponentScan 扫描注册为 bean依赖中的 Component 注解也需要被 ComponentScan 扫描注册为 bean依赖中的配置类中的 Bean 注解要么被 ComponentScan 扫描注册为 bean要么遵循 Spring 的规则创建 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件并写上配置类的全类名如果是通过 ComponentScan 扫描配置类的话不需要这个 imports 文件。但是如果不用 ComponentScan 的话就必须用 imports 文件声明配置类的位置。在 Spring Boot 的启动类中有一个 SpringBootApplication 注解Ctrl B 进入这个类发现这个类上面还有其他注解。SpringBootApplicationSpringBootConfiguration这是一个配置类ComponentScan扫描的路径默认是扫描启动类所在包及其下面的子包EnableAutoConfiguration从依赖中的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中获取自动配置类的路径根据 Conditional 注解这些配置类中的 Bean 修饰的方法的返回值注册成 bean那现在问题出现了如果我们要用其他第三方的 bean通过 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 这个文件只能获得配置类中 Bean 方法返回的 bean不能获得 Component 声明的 bean。如果要获得 Component 声明的 bean需要配置 ComponentScan 的路径但是我们一配置这个路径就能直接获得 Component 和 Bean 声明的 bean 了也不需要这个 imports 文件了啊。其实直接通过 ComponentScan 去指定路径的话是比较麻烦的。用极限法来假设一下你要用 1000 亿个依赖每个依赖都有自己的包名那不就要在 ComponentScan 中手动填写 1000 亿次这多麻烦啊。用 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 声明配置类的位置这个工作不是我们自己干的是制作这个依赖的人去完成的我们只需要引入依赖就可以使用了这就很方便。

相关新闻

普通烤火罩容易起火,新 e 选安全吗?

普通烤火罩容易起火,新 e 选安全吗?

2026/7/17 5:51:13

更安全。面料通过阻燃检测,烟头、取暖高温不易引燃,无阴燃风险,老人小孩居家使用更放心。

SpringBoot通过Moquette集成MQTT Broker快速实现设备管理消息订阅与发布

SpringBoot通过Moquette集成MQTT Broker快速实现设备管理消息订阅与发布

2026/7/17 5:51:13

一、引言 1.1 什么是 MQTT MQTT 是一种基于发布/订阅范式的轻量级消息传输协议。该协议专为计算资源受限、带宽有限以及网络连接不稳定的设备设计,具有报文结构简洁、功耗低、传输可靠等特点。 1.2 为什么选择 Moquette 当业务需求比较简单没必要或开发受限无法在服…

Dify 流程节点配置完全指南

Dify 流程节点配置完全指南

2026/7/17 5:51:13

Dify 流程节点配置完全指南 文档说明: 本文档依据 Dify 官方文档整理,覆盖工作流、对话流全部节点配置,每个节点附带可直接复制使用的实操配置示例,适配 Version1.13.3 版本。 目录: 一、基础入口与输出节点 2 1.1 开始…

深度学习模型压缩技术:量化、剪枝与蒸馏实战

深度学习模型压缩技术:量化、剪枝与蒸馏实战

2026/7/17 7:31:17

1. 深度学习模型压缩的核心价值与挑战在移动端和嵌入式设备上部署深度学习模型时,我们常常面临一个尴尬的现实:实验室里准确率高达95%的CNN模型,放到手机上运行需要3秒才能处理一张图片,内存占用直接爆掉512MB。这就是模型压缩技术…

Codex App Windows版worktree实战:多环境隔离与配置管理

Codex App Windows版worktree实战:多环境隔离与配置管理

2026/7/17 7:31:17

1. 项目概述:为什么一个“worktree”能让你从Codex App Windows用户变成真正高手?Codex App Windows版,最近在技术写作、文档自动化和本地AI辅助编程圈子里火得有点突然。很多人第一次打开它,发现界面清爽、响应快、中文支持还行&…

极速语音转写终极指南:如何使用faster-whisper实现4倍加速

极速语音转写终极指南:如何使用faster-whisper实现4倍加速

2026/7/17 7:31:17

极速语音转写终极指南:如何使用faster-whisper实现4倍加速 【免费下载链接】faster-whisper Faster Whisper transcription with CTranslate2 项目地址: https://gitcode.com/GitHub_Trending/fa/faster-whisper 你是否还在为语音转写速度慢、内存占用高而烦…

昉·星光2 RISC-V单板计算机GPU性能解析与优化

昉·星光2 RISC-V单板计算机GPU性能解析与优化

2026/7/17 7:31:17

1. 昉星光 2单板计算机的硬件架构解析作为全球首款面向边缘计算的RISC-V架构Linux单板计算机,昉星光2(VisionFive 2)采用了赛昉科技自主研发的惊鸿7100系列处理器。这款SoC的核心是采用64位RISC-V指令集的JH7110芯片,其四核设计主…

MySQL连接拒绝错误排查与解决方案

MySQL连接拒绝错误排查与解决方案

2026/7/17 7:31:17

1. MySQL连接拒绝错误的本质与常见场景当你在终端或应用程序中看到"Cant connect to MySQL server on xxx (61 "Connection refused")"这个错误时,本质上表示客户端无法与MySQL服务器建立TCP连接。这个错误发生在网络层,比认证错误&…

AI-Shoujo HF Patch安装配置全攻略:从原理到实战避坑指南

AI-Shoujo HF Patch安装配置全攻略:从原理到实战避坑指南

2026/7/17 7:21:17

1. 项目概述:为什么你需要HF Patch?如果你正在玩AI-Shoujo这款游戏,并且感觉原版内容在角色互动、场景构建或者功能扩展上有些“意犹未尽”,那么你大概率已经听说过HF Patch(High-Fidelity Patch,高保真增强…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/16 0:35:09

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/16 14:29:31

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/16 14:18:17

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

Cursor终端插件生态避坑指南:23个实测低效插件黑名单,附3个自研轻量替代方案

Cursor终端插件生态避坑指南:23个实测低效插件黑名单,附3个自研轻量替代方案

2026/7/17 0:00:57

更多请点击: https://intelliparadigm.com 第一章:Cursor终端插件生态避坑指南概览 Cursor 作为基于 VS Code 内核构建的 AI 原生编辑器,其终端插件生态虽活跃,但存在兼容性断层、权限策略突变与调试链路断裂等典型风险。开发者常…

ChatGPT写作提示词效率革命:单条提示词响应质量提升3.8倍的关键变量(附可复用提示词矩阵表)

ChatGPT写作提示词效率革命:单条提示词响应质量提升3.8倍的关键变量(附可复用提示词矩阵表)

2026/7/17 0:00:57

更多请点击: https://codechina.net 第一章:ChatGPT写作提示词效率革命:单条提示词响应质量提升3.8倍的关键变量(附可复用提示词矩阵表) 提示词工程已从经验试错迈入变量驱动的科学阶段。实证研究表明,影响…

DeepSeek V4替换Codex底座模型的实践与优化

DeepSeek V4替换Codex底座模型的实践与优化

2026/7/17 0:00:57

1. 为什么选择用DeepSeek V4替换Codex的底座模型去年我在开发一个智能代码补全工具时,发现Codex的默认底座模型在复杂业务逻辑场景下表现不尽如人意。经过多次测试对比,DeepSeek V4在以下几个关键指标上展现出明显优势:代码补全准确率&#x…