当前位置: 首页 > news >正文

【SpringBoot实践】编写一个自定义的starter,简单聊聊自动装配原理

文章目录

  • 1. 概述
  • 2.自动装配原理及自定义starter编写
    • 2.1.简单聊聊SpringBoot的自动装配原理
    • 2.2.自定义starter编写
      • 2.3.1.项目初始化及代码编写
      • 2.3.2.配置文件编写
      • 2.3.3.校验结果
  • 3.总结

1. 概述

我们在使用SpringBoot做开发的时候经常会使用到starter,starter给我们提供了一些开箱即用的功能,例如我们想使用某个中间件的时候,只需要引入并在配置文件中写一些少量的配置就可以直接使用了,像Redis,Spring Data,mybatis以及RabbitMQ等等。
既然用来这么方便,那在我们做项目的脚手架的时候,通过starter做一些团队都能用上的基础包封装,后续团队开发起来需要使用的时候就方便了。那么本篇就来聊一聊如何的编写一个自定义的starter。

在之前的文章《XXL-JOB的执行器配置》中曾写到了,如果不想在每个使用到定时任务的服务中都去编写一套重复的配置,就可以使用SpringBoot的starter做一下封装,今天就来把这个坑填上。

使用版本为SpringBoot2的最后一个版本,2.7.18

2.自动装配原理及自定义starter编写

下面先简单的聊一下SpringBoot的自动装配原理是怎么回事,熟悉原理之后再自定义一个starer就是水到渠成的事情了。

2.1.简单聊聊SpringBoot的自动装配原理

我们可以知道的是,SpringBoot是通过扫描包获取的Bean定义,再经过实例化与初始化获得最终可以执行任务的bean对象,这种对Bean扫描再初始化的方式,依赖的是对扫描路径的配置(当然,SpringBoot的默认扫描路径就是Application类下的所有子包)。

那么问题来了,我们在使用三方jar包的时候,三方包的包路径与我们项目中的路径并不一致,这时候Spring应该如何扫描到jar包中Bean定义呢?
手动配置三方jar包的依赖路径倒是可以解决这个问题,但是不同的三方包,其包路径也不一样,我们不可能没新增一个新的包,就配置一下路径,这个时候就需要使用的SpringBoot的自动装配机制了


自动装配机制有点类似于SPI的思想,简单的说,就是在需要封装成starter的项目的META-INF加入一个配置文件,这个配置文件里面写了需要扫描的类的全类名,SpringBoot在启动的时候会获取到这个文件,扫描对应的类,并把需要加载的Bean加载到Spring的容器中
配置文件的路径有两种,分别是:

  • META-INF/spring.factories
  • META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

前者是相对旧一点的版本,并且在SpringBoot3.0后弃用,后者大概是在2.7版本后才新增,并且在3.0的时候正式使用(原因大概使用因为后者支持3.0的新特性,可以在编译时处理注解,性能优于前者)。
在这里插入图片描述
通过上图打开的文件,从左到右的顺序可以找到这行代码,同时也能找到下面的代码。
在这里插入图片描述
也就是说,需要扫描的Bean不管是写在其中的哪一个文件中,都可以被扫描到。

2.2.自定义starter编写

有了上面基础之后,就可以开始编写starter了,对于XXL-JOB执行器的封装,只需要简单的四步就可以了。

  • 创建一个2.7.18版本的SpringBoot项目
  • 将项目中的XXL-JOB执行器配置拷贝过来
  • 编写配置文件
  • 打包供其他项目引用

2.3.1.项目初始化及代码编写

初始化项目的时候需要注意命名规则,一般来说有两种规则:

  • Spring官方的starter:一般是spring-boot-starter-xxx的形式
  • 三方的starter:一般是xxx-spring-boot-starter的形式

可以看到,spring-boot-starter 一个在开头,一个在结尾,我们命名的时候也要注意这个规范,这里命名为my-xxl-job-spring-boot-starter
在这里插入图片描述

项目建好之后,将之前xxl-job文中的配置搬过来,新建两个类:

@ConfigurationProperties(prefix = "xxl.job.executor")
public class XxlJobProperties {/*** 在业务服务配置文件中配置*/private String appname;/*** 下面直接写死公司的配置*/private String adminAddresses = "http://ls.xxljob.cn/xxl-job-admin";private String accessToken = "default_token";private int port = 9999;private String logPath = "/data/applogs/xxl-job/jobhandler";private int logRetentionDays = 30;private String address ;private String ip;……忽略getter,setter 
}
@Configuration
@EnableConfigurationProperties({XxlJobProperties.class})
public class XxlJobConfig {@Bean@ConditionalOnMissingBean@ConditionalOnProperty(prefix = "xxl.job.executor", value = "appname")public XxlJobSpringExecutor xxlJobExecutor(XxlJobProperties xxlJobProperties) {XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(xxlJobProperties.getAdminAddresses());xxlJobSpringExecutor.setAppname(xxlJobProperties.getAppname());xxlJobSpringExecutor.setAddress(xxlJobProperties.getAddress());xxlJobSpringExecutor.setIp(xxlJobProperties.getIp());xxlJobSpringExecutor.setPort(xxlJobProperties.getPort());xxlJobSpringExecutor.setAccessToken(xxlJobProperties.getAccessToken());xxlJobSpringExecutor.setLogPath(xxlJobProperties.getLogPath());xxlJobSpringExecutor.setLogRetentionDays(xxlJobProperties.getLogRetentionDays());return xxlJobSpringExecutor;}
}

需要说明一下的是,@Conditional是Spring中的一个条件注解,其作用是让Bean在满足一定条件之后才会加载到Spring容器中,下面例举几个常见的注解:

  • @ConditionalOnProperty:根据配置文件中的属性是否存在、是否为某个值来加载 Bean。
    • prefix:配置属性的前缀
    • value:属性名
    • havingValue:当属性值等于指定值时条件成立
    • matchIfMissing:属性缺失时,是否视为满足条件,默认为 false
  • @ConditonalOnMissingBean(xx.class):容器中没有某个bean对象时才执行创建,不指定则默认是当前方法的返回值对应的bean对象。
  • @ConditionalOnBean(xx.class):与上面的相反,容器中有某个bean对象时才创建,用于需要一些依赖关系的时候。
  • @ConditionalOnClass(name = "com.example.SomeClass"):当指定类存在于类路径上时加载 Bean。
  • @ConditionalOnMissingClass("com.example.SomeClass"):当指定类不存在于类路径时加载 Bean。

2.3.2.配置文件编写

因为是2.7.x的版本,可以在resources下创建配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,并在配置文件中加入全类名

com.ls.config.XxlJobConfig

要在较低版本中实现自动配置,需要在 META-INF/spring.factories 文件中添加以下内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ls.config.XxlJobConfig

2.3.3.校验结果

配置完了之后的结构如下:
在这里插入图片描述
直接通过install打包后,用其他的SpringBoot引用,加入properties配置:

xxl.job.executor.appname=my-simple-executor

打好断点启动,成功进入断点,表示starter编写成功。
在这里插入图片描述

3.总结

本篇主要是简单介绍了一下SpringBoot的自动装配原理,同时通过XXL-JOB演示了一下如何创建一个自定义的starter,项目开发中可以通过这样的方式来创建一些脚手架工程。


http://www.mrgr.cn/news/65749.html

相关文章:

  • Nginx线程模型
  • 23.智能停车计费系统(基于springboot和vue的Java项目)
  • SystemC简明教程
  • 力扣刷题hot100题python实现
  • 基于python flask的知乎问答文本分析与情感预测系统
  • 深入 Prometheus 监控生态 - 第六篇:与 Grafana 实现系统全面监控(健康状态和任务状态看板)
  • 【强化学习理论基础-通用】(13)从零开始白话给你讲[数学原理]:蒙特卡洛(MC Basic),model-base 到 model-free 关键之处
  • Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)
  • Vue全栈开发旅游网项目(5)-景点详情模块API接口设计
  • 【论文速看】DL最新进展20241104-自动驾驶、图像超分、目标检测
  • Centos7.6离线安装软件
  • Flutter UI架构(3)
  • 2024年11月1日——世间轮回
  • Diffusion Model
  • Linux高阶——1103—修改屏蔽字信号到达及处理流程时序竞态问题
  • 论文翻译 | Evaluating the Robustness of Discrete Prompts
  • vulhub之phpmyadmin
  • DBA之路,始于足下
  • C++基础:测试
  • 使用Spring Boot搭建简单的web服务
  • 重大917该如何复习?难度大不大?重点是啥?
  • 解决缓存击穿的代码[最佳实践版]
  • PD取电快充协议芯片,XSP08Q在灯具中的应用
  • RT-Thread学习
  • 【Linux探索学习】第十弹——Linux工具篇(五):详解Linux 中 Git 工具的使用与相关知识点
  • 【无标题】基于SpringBoot的母婴商城的设计与实现