编写自己的SpringBoot-starter
前言
我们都知道可以使用SpringBoot快速的开发基于Spring框架的项目。由于围绕SpringBoot存在很多开箱即用的Starter依赖,使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置,而只需要关注业务即可。
例如我想要在SpringBoot项目中集成Redis,那么我只需要加入spring-data-redis-starter的依赖,并简单配置一下连接信息以及Jedis连接池配置就可以。这为我们省去了之前很多的配置操作。甚至有些功能的开启只需要在启动类或配置类上增加一个注解即可完成。
那么如果我们想要自己实现自己的Starter需要做些什么呢?下面就开始介绍如何实现自己的SpringBoot-xxx-starter。
原理
首先说说原理,我们知道使用一个公用的starter的时候,只需要将相应的依赖添加的Maven的配置文件当中即可,免去了自己需要引用很多依赖类,并且SpringBoot会自动进行类的自动配置。那么 SpringBoot 是如何知道要实例化哪些类,并进行自动配置的呢? 下面简单说一下。
首先,SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories
文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。
第二步,根据 spring.factories
配置加载AutoConfigure
类。
最后,根据 @Conditional
注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。
我们也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class})
指定自动配置哪些类。
实现
终于到了代码实现的步骤,接下来就开始编码我们自己的SpringBoot-starter。
第一步创建一个SpringBoot 项目,并添加下面两个依赖到pom.xml文件当中
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
其中 spring-boot-configuration-processor
的作用是编译时生成 spring-configuration-metadata.json
,此文件主要给IDE使用。如当配置此jar相关配置属性在 application.yml
,你可以用ctlr+鼠标左键点击属性名,IDE会跳转到你配置此属性的类中。
我们日常使用的Spring官方的Starter一般采取spring-boot-starter-{name}
的命名方式,如 spring-boot-starter-web
。
而非官方的Starter,官方建议 artifactId
命名应遵循{name}-spring-boot-starter
的格式。 例如:ysc-spring-boot-starter
。
<groupId>com.ysc</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
第二步编写我们的Service类
这里讲一下我们的Starter要实现的功能,很简单,提供一个Service
,包含一个能够将配置文件中配置的字符串根据传入的字符进行分割的方法String[] split(String separatorChar)
。
public class StarterService {
private String config;
public StarterService(String config) {
this.config = config;
}
public String[] split(String separatorChar) {
return StringUtils.split(this.config, separatorChar);
}
}
第三步编写配置文件读取类
@ConfigurationProperties("example.service")
public class StarterServiceProperties {
private String config;
public void setConfig(String config) {
this.config = config;
}
public String getConfig() {
return config;
}
}
第四步,编写AutoConfigure
类 ,这步是关键点
@Configuration
@ConditionalOnClass(StarterService.class)
@EnableConfigurationProperties(StarterServiceProperties.class)
public class StarterAutoConfigure {
@Autowired
private StarterServiceProperties properties;
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
StarterService starterService (){
return new StarterService(properties.getConfig());
}
}
解释一下代码中用到的几个注解:
@ConditionalOnClass
,当classpath
下发现该类的情况下进行自动配置。@ConditionalOnMissingBean
,当Spring Context
中不存在该Bean
时。@ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true")
,当配置文件中example.service.enabled=true
时。
下面列举SpringBoot中的所有@Conditional注解及作用
@ConditionalOnBean:当容器中有指定的Bean的条件下
@ConditionalOnClass:当类路径下有指定的类的条件下
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径下是否有指定的资源
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean @ConditionalOnWebApplication:当前项目是Web项目的条件下
最后一步,在resources/META-INF/
下创建spring.factories
文件,并添加如下内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autocinfigure.StarterAutoConfigure
至此,我们的一个Starter代码部分就是完成了,下面将项目安装到本地Maven仓库中。
发布
在项目根目录执行 mvn install
进行打包安装。
测试
将Starter项目的依赖添加到我们自己的SpringBoot项目中
<dependency>
<groupId>com.ysc</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在application.yml
配置文件中添加配置信息:
example
service
enabled: true
config: abc-des-dde,SSS-DRS-RE,SDR-SDFR-XXX
在本地使用JUnit
进行代码测试
@Autowired
private StarterService starterService;
@Test
public void starterTest() {
String[] splitArray = starterService.split(",");
System.out.println(splitArray);
}
好,到这我们的一个自定义Stater就完成了
编写自己的SpringBoot-starter的更多相关文章
- Springboot 系列(十五)如何编写自己的 Springboot starter
1. 前言 Springboot 中的自动配置确实方便,减少了我们开发上的复杂性,那么自动配置原理是什么呢?之前我也写过了一篇文章进行了分析. Springboot 系列(三)Spring Boot ...
- SpringBoot Starter缘起
SpringBoot通过SpringBoot Starter零配置自动加载第三方模块,只需要引入模块的jar包不需要任何配置就可以启用模块,遵循约定大于配置的思想. 那么如何编写一个SpringBoo ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第7节 SpringBoot常用Starter介绍和整合模板引擎Freemaker、thymeleaf_28..SpringBoot Starter讲解
笔记 1.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-b ...
- SpringBoot Starter机制 - 自定义Starter
目录 前言 1.起源 2.SpringBoot Starter 原理 3.自定义 Starter 3.1 创建 Starter 3.2 测试自定义 Starter 前言 最近在学习Sp ...
- 自定义springboot - starter 实现日志打印,并支持动态可插拔
1. starter 命名规则: springboot项目有很多专一功能的starter组件,命名都是spring-boot-starter-xx,如spring-boot-starter-loggi ...
- 从头带你撸一个Springboot Starter
我们知道 SpringBoot 提供了很多的 Starter 用于引用各种封装好的功能: 名称 功能 spring-boot-starter-web 支持 Web 开发,包括 Tomcat 和 spr ...
- SpringBoot starter 作用在什么地方?
依赖管理是所有项目中至关重要的一部分.当一个项目变得相当复杂,管理依赖会成为一个噩梦,因为当中涉及太多 artifacts 了. 这时候 SpringBoot starter 就派上用处了.每一个 s ...
- 【SpringBoot】编写一个自己的Starter
一.什么是Starter? 在开发过程中我们就经常使用到各种starter,比如mybatis-spring-boot-starter,只需要进行简单的配置即可使用,就像一个插件非常方便.这也是Spr ...
- 手写一个springboot starter
springboot的starter的作用就是自动装配.将配置类自动装配好放入ioc容器里.作为一个组件,提供给springboot的程序使用. 今天手写一个starter.功能很简单,调用start ...
- OpenFeign封装为springboot starter
OpenFeign是什么 随着业务的增多,我们的单体应用越来越复杂,单机已经难以满足性能的需求,这时候出现了分布式.分布式通讯除了RPC, REST HTTP请求是最简单的一种方式.OpenFeign ...
随机推荐
- Vue上传文件:ElementUI中的upload实现
一.上传文件实现 两种实现方式: 1.直接action <el-upload .利用before-upload属性 此种方式有个弊端,就是action是必选的参数,那么action如果和pos ...
- 笔记:IIFE 立即执行的函数表达式 +function ($) { }(window.jQuery);
在Bootstrap源码(具体请看<Bootstrap源码解析1>)和其他jQuery插件经常看到如下的写法: +function ($) { }(window.jQuery); 这种写法 ...
- [php-cookie] cookie 请求跨域,如何共享
cookie 请求跨域的问题, 假设我有两个域名,一个 m.example.com,另一个是 www.example.com . 那么我需要如何设置 cookie 才可以在这两个域名都实现共享呢? / ...
- Android-Java-Lock
此篇博客已售票例子为例,所以首先看一个synchronized(同步锁机制)的案例 synchronized(同步锁机制)的案例 package android.java.thread19; /** ...
- 分形之科赫(Koch)雪花
科赫曲线是一种分形.其形态似雪花,又称科赫雪花.雪花曲线.瑞典人科赫于1904年提出了著名的“雪花”曲线,这种曲线的作法是,从一个正三角形开始,把每条边分成三等份,然后以各边的中间长度为底边.分别向外 ...
- STF环境搭建(ubuntu)
一,环境搭建 1. linux 一些基础的工具要有: sudo apt-get update sudo apt-get install git sudo apt-get install lib32st ...
- Django:haystack全文检索详细教程
参考:https://blog.csdn.net/AC_hell/article/details/52875927 一.安装第三方库及配置 1.1 安装插件 pip install whoosh dj ...
- 发送短信功能(C#)
参考自:https://blog.csdn.net/whl632359961/article/details/73468115 https://www.cnblogs.com/ywl925/archi ...
- 关于css中float的理解
感觉css里的float是个非常神奇的东西,神奇之处在于,你知道它是什么意思,但是用的时候总是不知道怎么实现效果.又或者它会很容易地影响到别的元素和属性.所以今天打算尝试一下float的各种设置,看看 ...
- Android .9 图片
最初对 .9 图片不是十分理解,一些教程让人摸不到头脑. 最近重新研究终于明白了它的原理. 其实最重要的一点记住就可以了,就是 .9 图片的四条黑边的意义,每条黑边的意义都不一样: 顶部:在水平拉伸的 ...