学习自定义SpringBoot Starter组件 (超详细的图文教程,从理论到实战)

news2024/11/18 8:46:00

前言:

通过这篇文章 你能了解SpringBoot Starter的概念和用处 并且通过实战 自定义一个SpringBoot Starter 来实现数据脱敏的功能
加油 搬砖人~ 今天不学习,明天变垃圾。
在这里插入图片描述

一、什么是SpringBoot Starter?用SpringBoot Starter能带来什么好处?

学习一项技术的前提是搞清自己的需求和这项技术能为我们解决什么样的实际问题。
那我们的需求是了解SpringBoot Starter的特性,利用Starter 的特性 学会自定义Starter ,最后在自己的项目中使用自定义的Starter来简化配置 快速使用第三方组件或者自己提供的一些功能。

1、SpringBoot Starter概念的解释:
SpringBoot Starter是 Spring Boot框架中的一个关键概念,用于简化Spring应用程序的依赖管理和配置。
Starter通常包含了要使用特定功能所需的所有依赖项、配置和自动配置。
通俗点说Starter就是SpringBoot定义的一种规范,在Spring中我们想使用某个中间件无外乎下面三步
①、配置好需要的bean
②、将配置好的bean注册到Spring的IoC容器 (注意:IoC的全称是Inversion of Control,而不是Inverse of Control,IoC的写法采用了小写的"o",以与"of"之间的大写字母进行区分)
③、在代码中 使用@Resource 或者@Autowired从容器中注入需要的bean 开始使用

SpringBoot Starter 可以帮助我们简化①、②步的操作
也就是说使用SpringBoot Starter 我们可以将精力更多的放在功能的使用上 而不用过多的去关注bean的配置

2、用SpringBoot Starter有什么好处:
能够简化中间件的配置、将我们需要的bean自动配置好注入容器 方便开发者直接拿来使用
在企业中使用Starter封装中间件 能减少重复配置 拿来即用 提高开发效率

二、熟悉Spring和配置相关的注解

要想自定义Starter 就要先理解SpringBoot和配置相关的注解
①、 @ConfigurationProperties
@ConfigurationProperties注解用于将外部配置文件(如application.properties或application.yml)中的属性值绑定到Java类的属性上
还支持配置前缀(prefix = “xxx”)
例如:
下面是个properties文件

desensitization.enabled=true

上面的配置能够直接配置到下面的java类中

@Data
@ConfigurationProperties(prefix = "desensitization")
public class DesensitizationProperties {
    private Boolean enabled;
}

②、@EnableConfigurationProperties(xxx.class)
这个注解是用来配合@ConfigurationProperties注解一起使用的 括号内可以设置你的配置类
例如 @EnableConfigurationProperties(DesensitizationProperties.class)
把@EnableConfigurationProperties注解放在某个配置类上或者启动类上 即可生效、能够将DesensitizationProperties类注册到Spring容器内

③、@Import
导入配置类:使用@Import注解可以将其他配置类导入到当前配置类中
导入组件:使用@Import注解导入一个普通的Java类时,该类将会被注册为Spring容器管理的Bean

④、@EnableAutoConfiguration
自动配置Spring环境:自动配置Spring Boot应用程序的各种配置项,如数据源、数据访问框架、Web框架等。通过这种方式,可以简化配置和启动过程,快速搭建和运行Spring Boot应用程序。

激活自动配置类:@EnableAutoConfiguration会根据项目的classpath中存在的类、依赖和配置文件等信息,自动搜索并加载满足条件的自动配置类,将其添加到Spring应用程序上下文中
如下图所示 SpringBoot有这么多默认的配置类
在这里插入图片描述
接下来我们自定义Starter 就会用到
@ConfigurationProperties
@EnableConfigurationProperties

三、感受Starter带给我们的方便 自己实现一个Starter 实现数据脱敏功能

简单说一下 数据脱敏
例如: 调用获取人员信息接口 人员信息有手机号
数据库存的是 18888888888 接口返回给前端的是 188****8888 隐藏部分敏感数据 就叫数据脱敏
在实际项目中有时候会用到这个功能

那我们就实现一个简单的数据脱敏功能 并且封装成SpringBoot的starter 然后在项目中去使用它

①、先实现数据脱敏功能(这个不重要 只说下大概思路)

使用自定义的Jackson序列化器结合Hutools工具 实现数据脱敏
大致的步骤是:

  • 1、创建一个自定义的Jackson序列化器,继承com.fasterxml.jackson.databind.JsonSerializer抽象类。
    重写serialize方法,实现ContextualSerializer接口 重写createContextual方法
  • 2、制定一个注解用于标记需要脱敏的字段
  • 3、当使用@RestController或者@ResponseBody注解将Controller层返回对象转换为JSON时,Jackson会自动使用自定义的序列化器对标注了自定义注解的字段进行脱敏处理

先看下效果
下面是段测试代码

@RestController
@RequestMapping(value = "/test")
public class TestController {

    @RequestMapping(value = "/a", method = RequestMethod.GET)
    public User test() {
        User user = new User();
        String phone = "18888888888";
        user.setPhone(phone);
        return user;
    }
}

@Data
class User {
    @Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE)
    private String phone;
}

浏览器访问返回结果
在这里插入图片描述

②、给自己的Starter取个牛逼的名字

Spring Boot官方发布的Starter名称规范则是:spring-boot-starter-xxx
官网推荐我们自己的starter命名规则为:xxx-spring-boot-starter
为了见名知义 就取个直观点的名字 就叫 data-desensitization-spring-boot-starter (够长吧^_^ 量了下 起码有5厘米!)

③、创建data-desensitization-spring-boot-starter 项目 (继续往下看 有源码可以去下载)

1、创建一个maven项目并在resources目录下 新建 META-INF目录 再在META-INF目录 下新建 spring.factories文件
(spring.factories的目的是 在Spring Boot应用程序启动时,Spring框架会扫描spring.factories文件,解析其中的配置,自动加载和应用这些自动配置类 )
在这里插入图片描述
2、然后再新建 spring-configuration-metadata.json文件 (这个文件是给配置文件添加注释用的,可以自己新建 也可以引入spring-boot-configuration-processor这个maven依赖来通过在配置类的属性上添加javadoc注释 然后打包的时候就会自动根据javadoc注释生成 spring-configuration-metadata.json文件 )

最后效果就是你在properties或者yml里面写配置信息的时候会有提示 像下面这样:
在这里插入图片描述
3、引入基础的 Spring Boot Starter依赖

   <!-- 添加Spring Boot Starter依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

4、创建自动配置类
在这里插入图片描述
5、在spring.factories文件里 配置自己的配置类的全路径类名
使用\ 是为了方便阅读 如果有多个 就用 ,\
在这里插入图片描述
6、maven install 打包 就能在其他项目中引用了
下面是打包好的Starter maven坐标

<dependency>
    <groupId>org.example</groupId>
    <artifactId>data-desensitization-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

自己实现一个starter 实现数据脱敏功能 源码 点击下载

推荐自己去看看源码 很容易看懂 看过源码之后 可以自己参考源码再敲一遍
然后自己新建一个springboot项目 去验证下自己写的starter好不好用

测试项目的源码 点击下载

需要先下载 数据脱敏的 starter install 到本地仓库之后 再去启动测试项目

四、讲个小故事 自己动手把一个第三方工具封装成starter使用

提供个思路 例如 自己再写个 线程池 Starter 自己实现一个线程池 注入到容器 提供给别的项目用 再写一些线程池的参数配置 支持外部配置线程池子关键参数等功能

这里再结合现实的一个工作场景来写个使用Starter的小故事加深大家的印象

故事开始
你是小黑今年刚毕业 在投了888份简历之后,最终拿到了二哈公司的offer。 工资9000块一个月。

二哈公司有个 微服务项目的 定时任务模块 功能比较单一 每次新增定时任务都需要改动大量代码 而且任务失败没有通知机制 已经无法满足日益复杂的定时任务需求。

这天你的开发组长秀逗找到你。

秀逗: 小黑 我们公司 狗头项目的定时任务模块现在需要升级 硬性要求是 必须要有任务失败的通知机制 并且定时任务模块要和业务代码完成解耦。给你2天时间把这个活干了,我最近比较忙 要不然这个活就我自己干了!

小黑: 心里默念(2天?逗我呢 我光去实现一个通知机制就得1天了吧 还得去考虑解耦 还有30多个微服务要配置 2天确定不是逗我?) 额~~
算了 刚入职 就说2天干不了 别被公司优化了 , 额 ~ 好的秀逗组长 我这就去干~ 。

此时你内心开始思考,就给2天 而且狗头项目有30多个微服务 自己去实现肯定是不现实了
于是打开百度 查看下有哪些定时任务的轮子
于是你查到了 LTS 、SchedulerX、xxl-job、PowerJob、QuartZ

然后去对比下 又发现SchedulerX要收费 , LTS没有通知告警机制
经过对比 你发现xxl-job貌似不错
好的 接下来你又去部署了xxl-job服务端, 在项目中依赖了 xxl-job的客户端依赖 去配置了xxl-job的配置项 ,小试了一把 呦 这个不错 挺好用
就是你了 xxl-job 你就是我要找的那个靓仔 , 一天过去了~

开始改造30多个微服务 让他们都成为xxl-job的执行器 这个时候你发现 竟然要配置30多份配置文件 要疯了
这个时候时间来到了第二天中午 ~

秀逗: 小黑昨天给你的任务搞得怎么样了?
小黑:额 搞 搞 搞 的差不多了 ~ ~
秀逗: 不错 下午搞好了 给我演示看下。
小黑: ~ ~ ~ 好。

此时你心中: WTF 30多个 微服务配置想搞死我 还有几个小时就下午了…

正在煎熬的时候你突然想到了 曾经看到过一篇文章 名字叫做 学习自定义SpringBoot Starter组件 (超详细的图文教程,从理论到实战)
你茅塞顿开 ,想到可以使用starter 把配置信息封装一下 每个微服务只要依赖封装的Starter 就可以不用去重复配置了
太棒了 现在就干

①、
新建微服务 goutou-job-spring-boot-starter
pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.goutou</groupId>
    <artifactId>goutou-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>

    <dependencies>
        <!--xxl-job 依赖-->
        <dependency>
            <groupId>com.xuxueli</groupId>
            <artifactId>xxl-job-core</artifactId>
            <version>2.3.1</version>
        </dependency>

        <!--引入这个依赖,对spring.factories 文件添加 注释-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>2.3.2.RELEASE</version>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <optional>true</optional>
        </dependency>
       
    </dependencies>
</project>

注意 <optional>true</optional> 的含义是 引用这个依赖 的项目 不会把 带 <optional>true</optional>的依赖引入到项目中

编写配置类 注册XxlJobSpringExecutor 到Spring容器 xxl-job运行时需要这个bean

package com.goutou.config;

import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(XxlJobAutoConfiguration.class)
@Slf4j
public class XxlJobAutoConfiguration {

    @Bean
    public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties properties) {
        log.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(properties.getAdminAddresses());
        xxlJobSpringExecutor.setAppname(properties.getAppname());
        xxlJobSpringExecutor.setAddress(properties.getAddress());
        xxlJobSpringExecutor.setIp(properties.getIp());
        xxlJobSpringExecutor.setPort(properties.getPort());
        xxlJobSpringExecutor.setAccessToken(properties.getAccessToken());
        xxlJobSpringExecutor.setLogPath(properties.getLogPath());
        xxlJobSpringExecutor.setLogRetentionDays(properties.getLogRetentionDays());
        return xxlJobSpringExecutor;
    }

}

编写配置文件

package com.goutou.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "goutou.job")
@Data
public class XxlJobProperties {

    /**
     * xxl-job 后台地址
     */
    private String adminAddresses;
    /**
     * 可选
     */
    private String accessToken;
    /**
     * 执行器名称 建议写  当前应用名称前缀-xxl-job
     */
    private String appname;
    /**
     * 可选
     */
    private String address;
    /**
     * 可选
     */
    private String ip;
    /**
     * 可选
     */
    private int port;
    /**
     * 日志地址
     */
    private String logPath;
    /**
     * 日志保存时长 单位 天
     */
    private int logRetentionDays;

}

编写spring.factories 文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.goutou.config.XxlJobAutoConfiguration

你打包到本地仓库 先测试 没问题之后 上报狗头公司经过批准后 可以deploy 到公司的maven仓库

整个项目的代码结构如下:
在这里插入图片描述
你最终在30多个微服务 都引入了

<dependency>
   <groupId>com.goutou</groupId>
   <artifactId>goutou-spring-boot-starter</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>

并在 对应微服务的yml添加了 少量配置 就按时完成了定时任务模块的改造

秀逗组长在下午的评审中对你的工作效率赞赏有加,于是便找你谈话~

秀逗:小黑 ,我就知道你小子可以,效率挺高,不愧是我的人~ 狗头项目目前 没有对分布式事务进行处理 只有部分复杂业务通过回调机制实现简单的数据回滚 你给狗头项目写一个分布式事务组件 用来支持狗头项目的分布式事务 提高狗头项目的数据一致性 今天周三了 周五下午完成 给我汇报吧 主要是我太忙了 要不然我就自己写了!

小黑: 额(额 额~ ~ ~ 未完待续 ~ ~ ~)

所有的学习都是站在巨人的肩膀上:
参考文章:
https://javaguide.cn/system-design/schedule-task.html#powerjob
https://zhuanlan.zhihu.com/p/515380149
https://www.cnblogs.com/xiaoymin/p/14131982.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1036105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【04】FISCOBCOS扩容新节点

官方文档https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/tutorial/add_new_node.html 为节点生成证书并启动 每个节点都需要有一套证书来与链上的其他节点建立连接,扩容一个新节点,首先需要为其签发证书。为新节点生成私钥证书 接下来的操作都在nodes/…

MQ---第一篇

系列文章目录 文章目录 系列文章目录一、简述RabbitMQ的架构设计二、RabbitMQ如何确保消息发送 ? 消息接收?一、简述RabbitMQ的架构设计 Broker:rabbitmq的服务节点 Queue:队列,是RabbitMQ的内部对象,用于存储消息。RabbitMQ中消息只能存储在队列中。生产 者投递消息到队…

百度SEO优化的技巧大全(全面掌握SEO优化方法)

百度优化SEO内容优化介绍 为了提高网站在百度搜索结果中的排名&#xff0c;需要进行百度SEO优化&#xff0c;其中内容优化是非常重要的一环。内容优化包括网站结构、网页质量、关键词密度等方面。首先&#xff0c;网站结构应该简洁清晰&#xff0c;方便用户导航和搜索引擎爬虫…

LeetCode_二叉树_中等_1448.统计二叉树中好节点的数目

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你一棵根为 root 的二叉树&#xff0c;请你返回二叉树中好节点的数目。「好节点」X 定义为&#xff1a;从根到该节点 X 所经过的节点中&#xff0c;没有任何节点的值大于 X 的值。 示例 1&#xff1a; 输…

【AI视野·今日NLP 自然语言处理论文速览 第三十九期】Fri, 22 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Fri, 22 Sep 2023 Totally 59 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers LongLoRA: Efficient Fine-tuning of Long-Context Large Language Models Authors Yukang Chen, Shengju Qia…

基于若依ruoyi-nbcio增加flowable流程待办消息的提醒,并提供右上角的红字数字提醒(八)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 这个部分是这个单元最后内容了&#xff0c;就是点击消息更多的一些代码与逻辑。 1、需要在我的个人中心里…

Plant Simulation 与Web交互 V3.0工具

Plant Simulation WebTool V3.0工具&#xff0c;仅需简单设置&#xff0c;web与Plant Simulation可以双向通信&#xff0c;Web端可以缩放、旋转、平移操作 WebTool 工具

软件测试笔试

作者&#xff1a;爱塔居 专栏&#xff1a;软件测试 文章简介&#xff1a;记录了我在笔试、面试过程中遇见的一些小问题 1.软件的生命周期&#xff1a;需求分析、计划、设计、编码、测试、运行维护 2.软件测试的生命周期&#xff1a;需求分析、测试计划、测试设计/开发、测试执…

Vue.js 2—插槽 Slots

我们已经了解到组件能够接收任意类型的 JavaScript 值作为 props &#xff0c;但组件要如何接收模板内容呢? 在某些场景中&#xff0c;我们可能想要为子组件传递一些模板片段&#xff0c;让子组件在它们的组件中渲染这些片段。 此处&#xff0c;传递的是标签结构而不再是数据…

libpcap之PF_PACKET协议族

一、kernel中PF_PACKET协议族注册 af_packet.c module_init(packet_init);static int __init packet_init(void) {int rc proto_register(&packet_proto, 0);if (rc ! 0)goto out;sock_register(&packet_family_ops);register_pernet_subsys(&packet_net_ops);r…

威胁追踪如何增强您的网络安全态势

网络威胁的复杂性、频率和影响正在加剧。2022 年&#xff0c;勒索软件攻击达到2.361 亿次&#xff0c;其中 39% 的英国企业遭受网络攻击。 这些攻击需要工具和资源来识别和纠正漏洞&#xff0c;以在云环境中维护强大的安全框架&#xff0c;从而降低数据泄露和合规违规的风险。…

SpringCloud Alibaba - Sentinel篇

一、Sentinel快速入门 Sentinel官网地址&#xff1a;https://sentinelguard.io/zh-cn/index.html Sentinel项目地址&#xff1a;https://github.com/alibaba/Sentinel Sentinel是阿里巴巴开源的一款微服务流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量限流、熔…

计算机组成原理之初识计算机硬件,帮你拆开电脑看看里面的组成!!!

大家好&#xff0c;欢迎阅读《计算机组成原理》的系列文章&#xff0c;本系列文章主要教内容是从零学习计算机组成原理&#xff0c;内容通俗易懂&#xff0c;大家好好学习吧&#xff01;&#xff01;&#xff01; 更多的优质内容&#xff0c;请点击以下链接查看哦~~ ↓ ↓ ↓ …

Java实验案例(一)

目录 案例一&#xff1a;买飞机票 案例二&#xff1a;开发验证码 案例三&#xff1a;评委打分 案例四&#xff1a;数字加密 案例五&#xff1a;数组拷贝 案例六&#xff1a;抢红包 案例七&#xff1a;找素数的三种方法 案例八&#xff1a;打印乘法口诀表 案例九&#x…

若依微服务如何处理Long类型精度丢失问题?

当字段实体类为Long类型且值超过前端js显示的长度范围时会导致前端回显错误。 目录 1、ruoyi-common-security模块添加JacksonConfig配置全局序列化 2、增加指定配置类信息

20230924清远博物馆和图书馆

为了漂流来清远&#xff0c;但是一个城市&#xff0c;想快速了解她的年龄&#xff0c;不就得去博物馆图书馆吗&#xff0c;云想衣裳花想容&#xff0c;春风拂槛露华浓。若非群玉山头见&#xff0c;会向瑶台月下逢。 学校她也曾因历史而不断迁移。 清远她呀&#xff0c;原来已…

ortools在idea中导入失败解决方案

这里写目录标题 错误描述解决方案 <dependencies><!-- https://mvnrepository.com/artifact/com.google.ortools/ortools-java --><dependency><groupId>com.google.ortools</groupId><artifactId>ortools-java</artifactId><ver…

UWB高精度定位系统 超宽带技术

说到定位我们并不陌生&#xff0c;定位技术一直与我们的生活密不可分&#xff0c;比如最常见的车辆导航。 根据使用场景&#xff0c;定位技术分为室内定位和室外定位。 室外定位主要依靠GPS&#xff0c;北斗&#xff0c;GLONASS&#xff0c;伽利略等全球卫星定位导航系统。室内…

【linux】进程等待,进程替换

进程等待&#xff0c;进程替换 1.进程等待1.1进程等待必要性1.2进程等待的方法1.2.1wait方法1.2.2waitpid方法1.2.3通过宏得到退出码1.2.4 阻塞vs非阻塞 2.进程替换2.1进程替换的目的2.2execl替换函数2.3理解原理2.4其他替换接口2.4.1execl2.4.2execlp2.4.3execv2.4.4execvp2.4…

什么是JavaScript中的IIFE(Immediately Invoked Function Expression)?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ JavaScript中的IIFE⭐ 示例⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们…