引言

上篇文章《天天用SpringBoot,它的自动装配原理却说不出来》我们有说springBoot的自动装配怎么实现的(建议最好先看下篇文章,因为前后有关系),这篇文章的话我们就自己来实现一个SpringBootstarter吧。废话不多说我们还是直入主题吧。

什么是Spring Boot Starter呢?我们直接来看看官网是怎么介绍的吧。

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.

纳尼,一大堆的英文,这还有兴趣接着往下看吗?是不是看到这直接退出了。都到门口了,不进来喝杯茶再走嘛?看都看到这了还是接着继续往下看吧。我们先不解释这一段话是什么意思,我们可以看看starter的出现给我们解决了什么问题。
我们还是以上述官网的例子来进行说明比如说我们需要在Spring 中适应JPA来操作数据库。
在没有springBoot-starter之前,我们需要引入jpa的步骤

  • 通过maven 引入jdbc的依赖、以及jpa相关的各种依赖
  • 编写jpa相关的配置文件
  • 网上各种查询找资料进行调试,调试的过程对于新手可能会有点奔溃会遇到各种奇奇怪怪的问题,jar包冲突啊,这个jar包下载不下来,缺少某个jar包。
  • 终于在经历千辛万苦,哼次哼次的解决各种问题之后终于把项目跑起来了,然后把这次整合jpa遇到的问题,以及整合的步骤都一一的详细记录下来。方便下次在需要整合jpa的时候直接copy就好了。
    我们以前在没有starter之前是不是都是这么玩的。这样的缺点是不是也非常显著,比如过程复杂、需要不停的粘贴复制(不过这是程序员经常干的事情了,也不在乎多一两次了)、整合其它组件到自己的项目变的困难,效率低下。这也就造成了996的程序员比较多了(晚上就不能够回去69了)。

SpringBoot Starter的出现

我们可以看下SpringBoot 现在都为我们提供有哪些starter,我这边这截图了部分starter,更多的请点击https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters

starter的实现:虽然我们每个组件的starter实现各有差异,但是它们基本上都会使用到两个相同的内容:ConfigurationPropertiesAutoConfiguration。因为Spring Boot提倡“约定大于配置”这一理念,所以我们使用ConfigurationProperties来保存我们的配置,并且这些配置都可以有一个默认值,即在我们没有主动覆写原始配置的情况下,默认值就会生效。除此之外,starterConfigurationProperties还使得所有的配置属性被聚集到一个文件中(一般在resources目录下的application.properties),这样我们就告别了Spring项目中XML地狱。
starter的出现帮把我们把各种复杂的配置都封装起来了,让我们真正的可以达到了开箱即用。不仅降低了我们使用它的门槛,并且还大大提高了我们的开发效率。正如前面所说《SpringBoot自动装配》让我们有更多的时间去陪女朋友。

实现自己的SpringBoot Starter

命名规范

如果你快有孩子了,出生前你比较急的一定是起个名字。孩子的姓名标识着你和你爱人的血统,一定不会起隔壁老王的姓氏,肯定会招来异样的眼光。在maven中,groupId代表着姓氏,artifactId代表着名字。Spring Boot也是有一个命名的建议的。所以名字是不能够随随便便取得,可以按照官方的建议来取。

What’s in a name
All official starters follow a similar naming pattern; spring-boot-starter-*, where * is a particular type of application. This naming structure is intended to help when you need to find a starter. The Maven integration in many IDEs lets you search dependencies by name. For example, with the appropriate Eclipse or STS plugin installed, you can press ctrl-space in the POM editor and type “spring-boot-starter” for a complete list.
As explained in the “Creating Your Own Starter” section, third party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts. Rather, a third-party starter typically starts with the name of the project. For example, a third-party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-starter.

大概意思是
官方的 starter 的命名格式为 spring-boot-starter-{xxxx} 比如spring-boot-starter-activemq
第三方我们自己的命名格式为 {xxxx}-spring-boot-starter。比如mybatis-spring-boot-starter
如果我们忽略这种约定,是不是会显得我们写的东西不够“专业“。

自定义一个Starter

下面我们就来实现一个自定义的发送短信的starter,命名为sms-spring-boot-starter

  1. 引入pom
 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>provided</scope>
</dependency>
  1. 编写配置文件

发短信我们需要配置一些账号信息,不同的短信供应商,账户信息是不一样的,所以我们需要定义一个XXXXProperties 来自动装配这些账户信息。下面我们就以腾讯云和阿里云两家供应商为例;

@ConfigurationProperties(prefix = "sms")
@Data
public class SmsProperties { private SmsMessage aliyun = new SmsMessage(); private SmsMessage tencent = new SmsMessage(); @Data
public static class SmsMessage{ /**
* 用户名
*/
private String userName; /**
* 密码
*/
private String passWord; /**
* 秘钥
*/
private String sign; /**
*
*/
private String url; @Override
public String toString() {
return "SmsMessage{" +
"userName='" + userName + '\'' +
", passWord='" + passWord + '\'' +
", sign='" + sign + '\'' +
", url='" + url + '\'' +
'}';
}
}
}

如果需要在其他项目中使用发送短信功能的话,我们只需要在配置文件(application.yml)中配置SmsProperties 的属性信息就可以了。 比如:

sms:
aliyun:
pass-word: 12345
user-name: java金融
sign: 阿里云
url: http://aliyun.com/send
tencent:
pass-word: 6666
user-name: java金融
sign: 腾讯云
url: http://tencent.com/send

还记的@ConfigurationProperties注解里面是不是有个prefix 属性,我们配置的这个属性是sms,配置这个的主要一个作用的话是主要用来区别各个组件的参数。这里有个小知识点需要注意下当我们在配置文件输入sms我们的idea会提示这个sms有哪些属性可以配置,以及每个属性的注释都有标记,建议的话注释还是写英文,这样会显得你比较专业。

这个提示的话,是需要引入下面这个jar的。

  <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

引入这个jar之后,我们编译之后就会在META-INF文件夹下面生成一个spring-configuration-metadata.json的文件。

我们可以看到这个文件其实 是根据SmsProperties类的成员属性来生成的。

  1. 然后在编写短信自动配置类:
@EnableConfigurationProperties(value = SmsProperties.class)
@Configuration
public class SmsAutoConfiguration {
/**
* 阿里云发送短信的实现类
* @param smsProperties
* @return
*/
@Bean
public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){
return new AliyunSmsSenderImpl(smsProperties.getAliyun());
}
/**
* 腾讯云发送短信的实现类
* @param smsProperties
* @return
*/
@Bean
public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){
return new TencentSmsSenderImpl(smsProperties.getTencent());
}
}

编写我们的发送短信实现类:

public class AliyunSmsSenderImpl implements SmsSender {

    private SmsMessage smsMessage;

    public AliyunSmsSenderImpl(SmsMessage smsProperties) {
this.smsMessage = smsProperties;
} @Override
public boolean send(String message) {
System.out.println(smsMessage.toString()+"开始发送短信==》短信内容:"+message);
return true;
}
}
  1. 让starter生效

starter集成应用有两种方式:

  • 被动生效
    我们首先来看下我们熟悉的方式,通过SpringBootSPI的机制来去加载我们的starter。我们需要在META-INF下新建一个spring.factories文件keyorg.springframework.boot.autoconfigure.EnableAutoConfiguration, value是我们的SmsAutoConfiguration 全限定名(记得去除前后的空格,否则会不生效)。
  • 主动生效
    starter组件集成到我们的Spring Boot应用时需要主动声明启用该starter才生效,通过自定义一个@Enable注解然后在把自动配置类通过Import注解引入进来。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {
}

使用的时候需要在启动类上面开启这个注解。

5.打包,部署到仓库
如果是本地的话,直接通过mvn install命令就可以了。
如果需要部署到公司的仓库话,这个就不说了。
6. 新建一个新的SpringBoot项目引入我们刚写的starter

 <dependency>
<groupId>com.workit.sms</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

在项目配置文件配上短信账号信息

测试代码

@SpringBootApplication
@EnableSms
public class AutoconfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(AutoconfigApplication.class, args);
AliyunSmsSenderImpl aliyunSmsSender = applicationContext.getBean(AliyunSmsSenderImpl.class);
aliyunSmsSender.send("用阿里云发送短信");
TencentSmsSenderImpl tencentSmsSender = applicationContext.getBean(TencentSmsSenderImpl.class);
tencentSmsSender.send("用腾讯云发送短信");
}

运行结果:

SmsMessage{userName='java金融', passWord='12345', sign='阿里云', url='http://aliyun.com/send'}开始发送短信==》短信内容:用阿里云发送短信
SmsMessage{userName='java金融', passWord='6666', sign='腾讯云', url='http://tencent.com/send'}开始发送短信==》短信内容:用腾讯云发送短信

至此的话我们自定义的一个starter就已经完成了,这个starter只是一个演示的demo,代码有点粗糙,项目结构也有点问题。重点看下这个实现原理就好。赶紧动动小手去实现一个自己的starter吧。

总结

  • SpringBoot starter的出现,让我们项目中集成其他组件变得简单。它把简单给了别人,把复杂留给了自己。“牺牲小我,成就大我”的思想还是值得学习的。平时我们工作中,比如要开发一个组件、或者一个工具类,也应该尽可能的让使用方可以做到无脑使用,不要搞的太复杂,又能让使用者可以灵活扩展。

结束

  • 由于自己才疏学浅,难免会有纰漏,假如你发现了错误的地方,还望留言给我指出来,我会对其加以修正。
  • 如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。
  • 感谢您的阅读,十分欢迎并感谢您的关注。
    站在巨人的肩膀上摘苹果:
    https://www.cnblogs.com/tjudzj/p/8758391.html
    https://blog.springlearn.cn/posts/14644/

手把手教你实现自定义Spring Boot的 Starter的更多相关文章

  1. 手把手教你定制标准Spring Boot starter,真的很清晰

    写在前面 我们每次构建一个 Spring 应用程序时,我们都不希望从头开始实现具有「横切关注点」的内容:相反,我们希望一次性实现这些功能,并根据需要将它们包含到任何我们要构建的应用程序中 横切关注点 ...

  2. 自定义spring boot starter 初尝试

    自定义简单spring boot starter 步骤 从几篇博客中了解了如何自定义starter,大概分为以下几个步骤: 1 引入相关依赖: 2 生成属性配置类: 3 生成核心服务类: 4 生成自动 ...

  3. 自定义spring boot的自动配置

    文章目录 添加Maven依赖 创建自定义 Auto-Configuration 添加Class Conditions 添加 bean Conditions Property Conditions Re ...

  4. Spring Boot(3)---自定义spring boot starter 问题

    1. "Failed to process import candidates for configuration class [com.simple.....]": 主要原因: ...

  5. Sping Boot入门到实战之实战篇(一):实现自定义Spring Boot Starter——阿里云消息队列服务Starter

    在 Sping Boot入门到实战之入门篇(四):Spring Boot自动化配置 这篇中,我们知道Spring Boot自动化配置的实现,主要由如下几部分完成: @EnableAutoConfigu ...

  6. Spring Boot2 系列教程(六)自定义 Spring Boot 中的 starter

    我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小 ...

  7. 年轻人的第一个自定义 Spring Boot Starter!

    陆陆续续,零零散散,栈长已经写了几十篇 Spring Boot 系列文章了,其中有介绍到 Spring Boot Starters 启动器,使用的.介绍的都是第三方的 Starters ,那如何开发一 ...

  8. 自定义Spring Boot内置tomcat的404页面

    spring boot 的相关404页面配置都是针对项目路径下的(如果配置了 context-path) 在context-path不为空的情况下,如果访问路径不带context-path,这时候会显 ...

  9. 最详细的自定义Spring Boot Starter开发教程

    1. 前言 随着Spring的日渐臃肿,为了简化配置.开箱即用.快速集成,Spring Boot 横空出世. 目前已经成为 Java 目前最火热的框架了.平常我们用Spring Boot开发web应用 ...

随机推荐

  1. 《Machine Learning in Action》—— 白话贝叶斯,“恰瓜群众”应该恰好瓜还是恰坏瓜

    <Machine Learning in Action>-- 白话贝叶斯,"恰瓜群众"应该恰好瓜还是恰坏瓜 概率论,可以说是在机器学习当中扮演了一个非常重要的角色了.T ...

  2. Appium之测试微信小程序

    坚持原创输出,点击蓝字关注我吧 作者:清菡 博客:Oschina.云+社区.知乎等各大平台都有. 目录 一.往期回顾 二.测试微信小程序 1.准备工作 2.操作步骤 3.注意 4.强制设置安卓的进程 ...

  3. ASP.Net Core 3.1 使用gRPC入门指南

    主要参考文章微软官方文档: https://docs.microsoft.com/zh-cn/aspnet/core/grpc/client?view=aspnetcore-3.1 此外还参考了文章 ...

  4. JZOJ 2020.10.6 【NOIP2017提高A组模拟9.7】陶陶摘苹果

    陶陶摘苹果 题目 Description Input Output Sample Input 10 5 110 3 100 200 150 140 129 134 167 198 200 111 0 ...

  5. `prometheus-net.DotNetRuntime` 获取 CLR 运行指标原理解析

    prometheus-net.DotNetRuntime 介绍 Intro 前面集成 Prometheus 的文章中简单提到过,prometheus-net.DotNetRuntime 可以获取到一些 ...

  6. Fiddler 4 (过滤器的使用)

    1.先找到过滤器并且勾选 2.勾选 并填写要过滤的地址 3.运行 最终效果如下

  7. go语言的指针类型

    一.指针与引用的相关概念 什么是指针? 指针,全称为指针变量,是用来存储内存地址的一种变量.程序中,一般通过指针来访问其指向的内存地址中的内容(数据). 什么是引用? 引用,是C++中提出来的一种新的 ...

  8. 20192313 实验一《Linux基础与Java开发环境》实验报告

    20192313 2020-10-8 <数据结构与面向对象程序设计>实验1报告 课程:<程序设计与数据结构> 班级: 1923 姓名: 陈宇帆 学号:20192313 实验教师 ...

  9. 题解 CF1437G Death DBMS

    这题感觉不是很难,但是既然放在 \(\texttt{EDU}\) 的 \(\texttt{G}\) 题,那么还是写写题解吧. \(\texttt{Solution}\) 首先看到 "子串&q ...

  10. MySQL技术内幕InnoDB存储引擎(七)——事务

    什么是数据库的事务? 事务是访问并更新数据库中各种数据的一个程序执行单元.事务也是数据库区别于文件系统的一个重要特性. 事务需要满足的特性 1.原子性 原子性就是指数据库中的一个完整的事务是不可分割的 ...