「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。
starter 是 Spring Boot 中一种非常重要的机制,它可以将繁杂的配置统一集成到 starter 中,我们只需要通过 maven 将 starter 依赖导入到项目中,Spring Boot 就能自动扫描并加载相应的默认配置。
starter 的出现让开发人员从繁琐的框架配置中解放出来,将更多的精力专注于业务逻辑的开发,极大地提高了开发效率。
在一些特殊情况下,我们也可以将一些通用功能封装成自定义的 starter 进行使用,以下详细介绍如何自定义 starter。
- 命名规范
Spring Boot 提供的 starter 以 spring-boot-starter-xxx
形式命名。为了与 Spring Boot 生态提供的 starter 区分,官方建议第三方开发者或技术(例如 Druid、Mybatis 等等)厂商自定义的 starter 使用 xxx-spring-boot-starter
的形式命名,例如 mybatis-spring-boot-starter
、druid-spring-boot-starter
等等。
- 模块规范
Spring Boot 官方建议我们在自定义 starter 时,创建两个 Module: autoConfigure Module
和 starter Module
,其中 starter Module
依赖于 autoConfigure Module
。当然,这只是 Spring Boot 官方的建议,并不是硬性规定,若不需要自动配置代码和依赖项目分离,我们也可以将它们组合到同一个 Module 里。
3 分析第三方 starter
若要自定义 starter,我们可以从 mybatis-spring-boot-starter
与 mybatis-spring-boot-autoconfigure
中获取一些启发:
mybatis-spring-boot-starter
仅仅将其下引入的依赖整合到一起并对外提供一个依赖坐标(同时依赖于 mybatis-spring-boot-autoconfigure
),方便外部引用(解决版本冲突):
MybatisAutoConfiguration
是 mybatis-spring-boot-starter
的自动配置类,其中又加载了 MybatisProperties
配置类信息:
该自动配置类必须被 Spring 容器所识别并加载,才能加载其中 @Bean
定义的 Bean 组件,这时就需要依靠 Spring Boot 启动时加载的 spring.factories
配置文件来标识 MybatisAutoConfiguration
自动配置类,从而加载其中的 Bean。
大致了解 mybatis-spring-boot-starter
的起步依赖后,我们就可以来自定义所需的 starter 了。
⭐如果对自动配置原理仍有疑惑,可参考下该篇博客:juejin.cn/post/700560…
- 实现自定义 Starter
4.1 需求
自定义 scorpion-redis-spring-boot-starter
,要求当导入 redis 坐标时,Spring Boot 自动创建 Jedis 的 Bean。
4.2 实现步骤
- 创建
scorpion-redis-spring-boot-autoconfigure
模块 - 创建
scorpion-redis-spring-boot-starter
模块,并依赖于scorpion-redis-spring-boot-autoconfigure
模块 - 在
scorpion-redis-spring-boot-autoconfigure
模块中初始化 Jedis 的 Bean,并定义 META-INF/spring.factories 文件 - 在测试模块中引入自定义的
scorpion-redis-spring-boot-starter
依赖,测试获取 Jedis 的 Bean,操作 redis。
4.3 创建&开发 autoconfigure 模块
4.3.1 创建 scorpion-redis-spring-boot-autoconfigure
项目
创建一个 maven 模块:
4.3.2 修改 pom.xml
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
4.3.3 编写 RedisAutoConfiguration
@ConditionalOnClass(Jedis.class)
: 当项目中存在 Jedis 类(pom.xml
引入该依赖),则可以加载RedisAutoConfiguration
自动配置类,因为return new Jedis()
需要使用到Jedis.class
!@ConditionalOnMissingBean(name = "jedis")
: 当 Spring 容器中已存在 Jedis Bean,且name = "jedis"
,那么则无需再重复定义一个 Jedis Bean 通过@Bean
返回到 Spring 容器中了!
注:不要把 pom.xml 文件引入的类与 spring 容器中的类混淆了!
pom.xml 引入的是外部类,无法通过
@Component
、``@Repository、
@Controller、
@Service等注解将其注入到 Spring 容器中,只能通过
@Bean` 将其注入到 Spring 容器。Spring 容器:容器是Spring框架实现功能的核心,容器不只是帮我们创建了对象那么简单,它负责了对象整个的生命周期的管理——创建、装配、销毁。关于 Spring 的这个容器你最常听闻的一个术语就是 IOC 容器。总之一句话,我的应用程序里不用再过问对象的创建和管理对象之间的依赖关系了,都由 IOC 容器代劳,也就是说,我把对象创建、管理的控制权都交给 Spring 容器,这是一种控制权的反转,所以 Spring 容器才能称为 IOC 容器。不过这里要厘清一点:并不是说只有 Spring 的容器才叫 IOC 容器,基于 IOC 容器的框架还有很多,并不是 Spring 特有的。
1 | java复制代码package com.wyk.autoconfigure; |
4.3.4 编写 RedisProperties
1 | java复制代码package com.wyk.autoconfigure; |
4.3.5 定义 META-INF/spring.factories
1 | properties复制代码org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
4.3.6 完整的模块目录
4.4 创建&开发 starter 模块
4.4.1 创建 scorpion-redis-spring-boot-starter
模块
与 autoconfigure 同理,不再赘述:
4.4.2 修改 pom.xml
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
4.4.3 完整的模块目录
4.5 测试模块引入并测试自定义 Starter
4.5.1 pom.xml
1 | xml复制代码<!-- 测试自定义 Starter: scorpion-redis-spring-boot-starter: 所以引入该依赖 --> |
4.5.2 Spring Boot 启动类中测试
EnableStarterApplication.java:
1 | java复制代码package com.enable.starter; |
配置类生效:
自定义 Starter 测试成功!
希望本文对你有所帮助🧠
欢迎在评论区留下你的看法🌊,我们一起讨论与分享🔥
本文转载自: 掘金