前言最近在整理公司公开的启动器内容,也想写一篇关于启动器的文章,让更多不知名的伙伴掌握这个核心技能。本文从零到一包设计了starter,提供了可插拔starte
前言
最近在整理公司公开的启动器内容,也想写一篇关于启动器的文章,让更多不知名的伙伴掌握这个核心技能。
本文从零到一包设计了starter,提供了可插拔starter和元数据配置的说明,并在可插拔性上与开源zuul进行了比较。希望朋友们看完后有所收获。
文章的提纲如下:
Starterstarter定义starter好处自定义starterstarter名称创建springboot项目pom依赖项配置自动配置类spring.factories包仓库测试starter可插拔starter自定义可插拔starterzuul实现可插拔原则配置元数据结论
starterstarter 定义
Springboot starter类似于一个插件机制,抛弃了以前繁琐的配置,将复杂的依赖关系集成到starter中。
所有依赖模块都遵循常规的默认配置,并允许我们调整这些配置,即遵循“常规大于配置”的理念
starter 好处
starter的出现极大地帮助了开发者从繁琐的框架配置中解脱出来,从而更加专注于业务代码。
并且springboot官方提供了除企业级项目以外的不同场景下的starter依赖模块,可以很容易的集成到项目中。
比如springboot项目就需要依靠redis。我们只需要添加spring-boot-starter-data-redis依赖项,并配置一些必要的连接信息。
用户只需要参考starter依赖,springboot就可以自动加载项目所需的配置依赖,彻底摆脱不同依赖库参考和版本问题。
自定义 starterstarter 命名
官方启动包定义的artifactId是必需的,当然也可以忽略(毕竟你是你项目的负责人)
spr提供的官方启动通常命名为spring-boot-starter-{name}比如:
Spring-boot-starter-web,spring-boot-starter-activemq等。以下是一些官方名单。详情请参见springboot starter列表。
spring官方推荐的是非官方首发命名应该遵循{name}-spring-boot-starter的格式。
比如my batis:my batis-spring-boot-starter
创建 springboot 项目
Starter也是基于springboot项目创建的,所以第一步应该是创建springboot项目。
项目创建完成后,删除不需要的文件,目录如下:
├──pom.xml└──src├──main│├──Java│└──cn│└──machen│└──starter│└──demosprinbootstarter│└──资源
pom 依赖配置
pom.xml中的依赖非常简洁,除了项目的基本信息和父类引用,参考spring-boot-starter即可。
& lt?xml版本= & # 34;1.0"编码= & # 34;UTF-8 & # 34;?& gt& ltxmlns项目= & # 34;http://maven.apache.org/POM/4.0.0" xmlns:xsi = & # 34;http://www.w3.org/2001/XMLSchema-instance" xsi:schema location = & # 34;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" & lt;modelVersion & gt4 . 0 . 0 & lt;/model version & gt;& ltparent & gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gt弹簧-启动-启动-父母& lt/artifact id & gt;& lt版本& gt发布<。/version & gt;& ltrelative path/>;& lt!-从存储库中查找父级-& gt;& lt/parent & gt;& ltgroupId & gtcn . machen . starter & lt;/groupId & gt;& ltartifactId & gt演示-spring-boot-starter & lt;/artifact id & gt;& lt版本& gt0 . 0 . 1-快照& lt/version & gt;& lt属性& gt& ltjava.version & gt1.8 & lt/Java . version & gt;& lt/properties & gt;& lt依赖关系& gt& lt依赖性& gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gt弹簧靴起动器& lt/artifact id & gt;& lt/dependency & gt;& lt/dependencies & gt;& lt/project & gt;1234567891011121314151617181920212223242526
自动配置类
创建注册为spring bean的服务类,并为后续测试提供sayHello方法。
public class service bean { public String say hello(String name){ return String . format(& # 34;你好,世界,% s & # 34,姓名);}}
创建一个自动配置类,将ServiceBean声明为Bean,等待扫描并将其交付给spring ioc容器。
@ configuration public class AutoConfigurationTest { @ Bean public service Bean getServiceBean(){ return new service Bean();}}
spring.factories
在resources目录中创建新的META-INF文件夹,然后创建spring.factories文件。
文件中定义的Autoconfigure指定配置类是自动装配的配置。
org . spring framework . boot . auto configure . enable auto configuration = \ cn . machen . starter . demosprinbootstarter . auto configuration test
为什么要将resources/META-INF指定为spring.factories?你不能这样写。
springfactoriesloader # load factors负责加载自动装配类,扫描这个变量文件。
不按规定写,可以写,但是扫描不到你的自动配置类,可以停。
打包仓库
我们的starter必须被第三方或者其他项目引用,所以要把项目打包发布到仓库。
下面来看看maven命令的知识点。一般我们打包使用的命令比较多,分别是打包、安装、部署。
声明是所有三个命令都可以打包。有什么区别?
包装:
这个命令完成三个过程:项目编译、单元测试和打包。
安装:
在package命令的前提下,增加一个新的步骤,将新类型的包部署到本地maven仓库。
部署:
在install命令的前提下,增加一个新的步骤,将新类型的包部署到远程仓库(相当于同时部署本地和远程仓库的一个副本)。
而我们只是引用本地仓库,只需要执行install命令。两种方式分别是maven插件或者终端执行命令mvn clean install。
可以检查jar在对应的仓库坐标下是否部署成功。
测试 starter
如何才能检验新建的启动器是否成功?只需创建一个新项目并引用起始项目的坐标。
& lt?xml版本= & # 34;1.0"编码= & # 34;UTF-8 & # 34;?& gt& ltxmlns项目= & # 34;http://maven.apache.org/POM/4.0.0" xmlns:xsi = & # 34;http://www.w3.org/2001/XMLSchema-instance" xsi:schema location = & # 34;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" & lt;modelVersion & gt4 . 0 . 0 & lt;/model version & gt;& ltparent & gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gt弹簧-启动-启动-父母& lt/artifact id & gt;& lt版本& gt发布<。/version & gt;& ltrelative path/>;& lt!-从存储库中查找父级-& gt;& lt/parent & gt;& ltgroupId & gtcn . machen . starter & lt;/groupId & gt;& ltartifactId & gt演示-测试-弹簧-启动-启动器& lt/artifact id & gt;& lt版本& gt0 . 0 . 1-快照& lt/version & gt;& lt依赖关系& gt& lt依赖性& gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gt弹簧靴起动器& lt/artifact id & gt;& lt/dependency & gt;& lt!-入门包介绍-->:& lt;依赖性& gt& ltgroupId & gtcn . machen . starter & lt;/groupId & gt;& ltartifactId & gt演示-spring-boot-starter & lt;/artifact id & gt;& lt版本& gt$ { project.version } & lt/version & gt;& lt/dependency & gt;& lt依赖性& gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gt弹簧启动起动器测试& lt/artifact id & gt;& lt范围& gt测试& lt/scope & gt;& lt排除事项& gt& lt排除& gt& ltgroupId & gtorg . JUnit . vintage & lt;/groupId & gt;& ltartifactId & gtJUnit-vintage-engine & lt;/artifact id & gt;& lt/exclusion & gt;& lt/exclusions>。& lt/dependency & gt;& lt/dependencies & gt;& lt/project & gt;123456789101112131415161718192021222324252627282930313233343536373839
既然是测试,那通过什么样的标准呢?
根据我们starter中定义的代码,只要demo-test项目引用ServiceBean打印出相应的信息,就认为成功了。
使用src-main-test目录中的项目来创建自己的测试类。
@ springbootestclass DemoTestSpringBootStarterApplicationTests { @ auto wired private service bean service bean;@ Test void context loads(){ system . out . println(service bean . say hello(& # 34;马晨& # 34;));}}运行contextLoads测试方法,最后输出Hello World,马晨。
你以为这样就结束了吗?不不,硬核干知识才刚刚开始。
可插拔 starter自定义可插拔 starter
发令员就是发令员。为什么叫可插拔?
Pluggable,字面意思就是虽然我介绍了你的starter jar包,但是我可以通过条件来判断是否加载你的函数。
如果条件满足,就加载jar相关的配置,如果不满足,就在凉快的地方休息(更通俗一点,具体点就是模块插件,减少耦合)
实现可插拔性的方法有很多,比如配置文件密钥前缀或者自定义注释,但是这些都绕不过springboot的条件注释。
文章以自定义标注+条件标注的形式完成,其余不在此举例说明,可以上网搜索。
演示-弹簧-启动-启动器
1)首先,在项目中创建一个自定义注释。
@ target(element type . type)@ retention(retention policy . runtime)public @ interface enableautoconfigtest { } 2)AutoconfigurationTest类,然后重新打包到本地仓库。
@ Configuration @ ConditionalOnBean(annotation = enableautoconfigtest . class)public class AutoConfigurationTest { @ Bean public service Bean getServiceBean(){ return new service Bean();}演示-测试-弹簧-启动-启动器
1)在主程序中引用@EnableAutoConfigTest注释。
@ EnableAutoConfigTest @ spring boot application public类DemoTestSpringBootStarterApplication { public static void main(String[]args){ spring application . run(DemoTestSpringBootStarterApplication . class,args);}}测试可插拔启动器
运行上面测试类中运行的程序,这个例程操作自然可以正常打印我们的Hello World。
运行程序的人只正常运行,不是吗?删除@EnableAutoConfigTest,试一试。让我们看看这是不是迎接我们的东西。
通过字段& # 39;serviceBean & # 39;嵌套异常是org . spring framework . beans . factory . nosuchbeandetification异常:没有符合条件的类型为& # 39;cn . machen . starter . demosprinbootstarter . service bean & # 39;可用:需要至少1个符合autowire候选资格的bean。依赖注解:{ @ org . spring framework . beans . factory . annotation . auto wired(required = true)}当然正式环境不能这么粗糙,但是思路是一样的。
在参与公司搜索业务包starter之前,是使用上述自定义标注结合条件标注完成的。
其实除了本文中的可插拔实现,类似的思路就像springcloud zuul,因为这个东西玩不出来。
zuul 实现可插拔原理
我们通常通过在配置类上配置zuul annotation @ EnableZulproxy来开启Zuul注入。
关于@Import的评论在之前的文章#深度理解Spring @Import注册bean的不同方式中已经有详细的介绍。
看图中红班的作用。
根据课堂上的评论:
负责添加标签bean来触发{@ linkzuulproxyconfiguration}的激活
其实这里已经说清楚了,但是本着负责到底的好品质,我们会继续跟进。
与我们上面的定制可插拔启动器的想法一致,可插拔特性是通过一个标记来实现的。
不同的是,zuul用了一个无意义的bean来标记,而我们用的是注释。
配置元数据
看到项目配置文件中不知道好友输入时的智能提示,想知道如何实现?
以server.xxx为例,带着疑惑打开springboot源码包下的spring-configuration-metadata . JSON。
您熟悉默认值和描述吗?不就是上面建议的默认值和提示信息吗?
这种文件是怎么产生的?有两种方法。
通过建立 META-INF/spring-configuration-metadata.json 文件,开发者手动配置还有一种是通过注解 @ConfigurationProperties 方式自动生成
自动生成的肯定会先用。毕竟我就是这么懒的人。在starter包下,元数据配置只需要三个简单的步骤。
1)将spring-boot-configuration-processor包添加到引用pom.xml中
2)编写Properties配置类,以swagger为例。
@ Data @ Configuration @ Configuration properties(前缀= & # 34;斯瓦格& # 34;)public类swagger properties {/* * *文档扫描包路径*/private string base package = & # 34;";/** * title示例:订单创建接口*/私有字符串title = & # 34平台界面详情& # 34;;/* * *服务条款URL */privatestring termsofserviceurl = & # 34;https://www.xxxx.com/";/* * *版本号*/私有字符串版本= & # 34;v _ 1 . 0 . 0 & # 34;;}3)最后执行打包命令,更新本地仓库的jar包。
Mvclean install接下来更新demo-test-spring-boot-starter项目中的引用,然后在application.properties中测试它
这个X武器一定要跟亲朋好友普及一下
mybatis starter 如何实现
让我们介绍一下相关的pom包依赖关系。如果找不到相关的依赖包,可以在公共仓库上搜索。
公共仓库地址:https://mvnrepository.com/
& lt依赖性& gt& ltgroupId & gtorg . my batis . spring . boot & lt;/groupId & gt;& ltartifactId & gtmy batis-spring-boot-starter & lt;/artifact id & gt;& lt版本& gt1 . 3 . 2 & lt;/version & gt;& lt/dependency & gt;看看mybatis入门包都包含了什么,是否和我们的定制一致。
为什么?为什么这里面没有任何配置元信息?点开可能找到答案的pom.xml看看吧。
可以看到pom.xml包含了mybatis-spring-boot-auto configure,mybatis和mybatis-spring的依赖关系。
mybatis全局初始化的真正秘密在于MyBatis-spring-boot-auto configure。
这里很清楚,mybatis-spring-boot-auto configure包含了初始化配置类MybatisAutoConfiguration,其中完成了mybatis相关的初始化。
mybatis启动器的设计和我们上面说的自定义启动器有什么不同?
Mybatis starter什么都没做,只是做了一个组合依赖,自动配置包起到了初始化的作用。
Springboot有相同的想法,除了它以统一的方式发现所有包的自动配置实现。看spring-boot-auto configure-XXX . jar就能看出来。
然而,在我们的定制启动器中,对自动配置包的依赖较少。两者没有对错,只是不同设计的体现。这里不做任何建议,看个人喜好。
什么?你说要顺应主流,严格执行跳羚思想?
我料到你会这么想,所以我们也搬到了重量级选手网飞。
懂的人自然懂。让我们根据心情来决定开胃菜。一直写bug的互联网人~
结言
距离我上次发文章已经一周了。在这期间,我做了三件事,即:
DevOps 概念了解以及公司部分 DevOps 组件优化完成了个人技术博客网站的搭建通过迁移公众号开启了留言功能
DevOps
笔者之前接触DevOps不多,所以从概念上理解需要一些时间。
瀑布开发是什么?有什么优缺点?敏捷开发是什么?有什么优缺点?什么是 DevOps?CI/CD 又是什么?
经过这几天的了解和基础组件的搭建使用,掌握程度比以前好了很多,收获还是蛮大的。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。
作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/126865.html