自己实现一个Starter

自己实现SpringBoot里面的Starter

文章目录

  • 自己实现一个Starter
    • 原理
    • 核心知识
    • 开发自己的Starter
      • 创建Maven工程
      • 编写Servcie
      • 编写配置属性类
      • 编写自动配置类
      • 最后一步:添加spring.factories文件
    • 测试

原理

一个公用是starter我们只需要引入pom文件,SpringBoot就会进行自动配置。那么SpringBoot是如何知道要实例化哪些类,并进行简单配置呢?

  1. 首先,SpringBoot在启动时会去依赖的Starter包中寻找resources/META-INF/spring.factories 文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。

  2. 第二步,根据 spring.factories配置加载AutoConfigure

  3. 最后,根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。

    我们也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自动配置哪些类。

可以认为starter是一种服务——使得使用某个功能的开发者不需要关注各种依赖库的处理,不需要具体的配置信息, 由Spring Boot自动通过classpath路径下的类发现需要的Bean,并织入相应的Bean。举个栗子,spring-boot-starter-jdbc这个starter的存在, 使得我们只需要在BookPubApplication下用@Autowired引入DataSource的bean就可以,Spring Boot会自动创建DataSource的实例。

核心知识

1. @Conditional注解

核心就是条件注解 @Conditional ,使用方式如下

//当项目当前Classpath存在 HelloService的时候 后面的配置才生效
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {}

SpringBoot许多源码里面,都会出现条件注解,这就是Starter配置的核心之一。

  1. spring.factories 文件,这个是springboot启动会扫描的文件,然后寻找所依赖的jar包,写法如下
org.springframework.boot.autoconfigure.EnableAutoConfiguration =
//等于号后面是定义的starter的路径
com.example.autocinfigure.StarterAutoConfigure

这里举个栗子:我们自己开发项目引入的mybatis-starter如下

同样能看到mybatis的spring.factories文件

打开后,如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

开发自己的Starter

所谓starter,就是一个普通的Maven项目

我们要实现的starter很简单, 提供一个Service, 包含一个sayHello() 方法

主要分为下面几步骤

  1. 创建Maven项目
  2. 编写service
  3. 编写属性类
  4. 编写自动配置类
  5. 创建spring.factories文件,打包

创建Maven工程

新建一个普通Maven项目

  • 命名:这里说下artifactId的命名问题,Spring 官方 Starter通常命名为spring-boot-starter-{name}spring-boot-starter-web

    Spring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式。

  • 注意其中 spring-boot-configuration-processor 的作用是编译时生成spring-configuration-metadata.json, 此文件主要给IDE使用,用于提示使用。如在intellij idea中,当配置此jar相关配置属性在application.yml, 你可以用ctlr+鼠标左键,IDE会跳转到你配置此属性的类中。

<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.xncoding</groupId><artifactId>simple-spring-boot-starter</artifactId><version>1.0.0-SNAPSHOT</version><packaging>jar</packaging><name>simple-spring-boot-starter</name><description>一个简单的自定义starter</description><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.4.RELEASE</version></parent><dependencies><!-- @ConfigurationProperties annotation processing (metadata for IDEs)生成spring-configuration-metadata.json类,需要引入此类--><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>
</project>

编写Servcie

public class ExampleService {private String prefix;private String suffix;public ExampleService(String prefix, String suffix) {this.prefix = prefix;this.suffix = suffix;}public String wrap(String word) {return prefix + word + suffix;}
}

编写配置属性类

@ConfigurationProperties("example.service")
public class ExampleServiceProperties {private String prefix;private String suffix;public String getPrefix() {return prefix;}public void setPrefix(String prefix) {this.prefix = prefix;}public String getSuffix() {return suffix;}public void setSuffix(String suffix) {this.suffix = suffix;}
}

其中@ConfigurationPropeties 注解是读取 application.yml中 以 example.service 开头的属性

编写自动配置类

@Configuration
@ConditionalOnClass(ExampleService.class)
@EnableConfigurationProperties(ExampleServiceProperties.class)
public class ExampleAutoConfigure {private final ExampleServiceProperties properties;@Autowiredpublic ExampleAutoConfigure(ExampleServiceProperties properties) {this.properties = properties;}@Bean@ConditionalOnMissingBean@ConditionalOnProperty(prefix = "example.service", value = "enabled",havingValue = "true")ExampleService exampleService (){return  new ExampleService(properties.getPrefix(),properties.getSuffix());}}

解释下用到的几个和Starter相关的注解:

1. @ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。
2. @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
3. @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"),当配置文件中example.service.enabled=true时。

最后一步:添加spring.factories文件

最后一步,在resources/META-INF/下创建spring.factories文件,内容供参考下面:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xncoding.starter.config.ExampleAutoConfigure

如果有多个自动配置类,用逗号分隔换行即可。

OK,完事,运行 mvn:install 打包安装,一个Spring Boot Starter便开发完成了。

测试

打包好了当然要测试一下看看了。另外创建一个SpringBoot工程,在maven中引入这个starter依赖, 然后在单元测试中引入这个Service看看效果。

<dependency><groupId>com.xncoding</groupId><artifactId>simple-spring-boot-starter</artifactId><version>1.0.0-SNAPSHOT</version>
</dependency>

修改application.yml配置文件,添加如下内容:

example.service:enabled: trueprefix: pppsuffix: sss

测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {@Autowiredprivate ExampleService exampleService;@Testpublic void testStarter() {System.out.println(exampleService.wrap("hello"));}
}

运行结果

ppphellosss

自己实现一个Starter相关推荐

  1. 如何自定义一个starter组件

    本文来说下如何自定义一个stater组件. 文章目录 概述 原理浅谈 术语介绍 starter组件命名规则 概述 我们都知道可以使用 SpringBoot 快速的开发基于 Spring 框架的项目.由 ...

  2. 手撸一个动态数据源的Starter 完整编写一个Starter及融合项目的过程 保姆级教程

    手撸一个动态数据源的Starter! 文章目录 手撸一个动态数据源的Starter! 前言 一.准备工作 1,演示 2,项目目录结构 3,POM文件 二.思路 三.编写代码 1,定义核心注解 Ds 2 ...

  3. 保姆级教程,手把手教你实现一个SpringBoot的starter

    引言 什么是Spring Boot Starter呢?我们直接来看看官网是怎么介绍的吧. ❝ Starters are a set of convenient dependency descripto ...

  4. springboot中下面哪一个作为jpa默认实现_天天在用SpringBoot,手撸一个的Starter试试!...

    引言 上篇文章<天天用SpringBoot,它的自动装配原理却说不出来>我们有说springBoot的自动装配怎么实现的,这篇文章的话我们就自己来实现一个SpringBoot的 start ...

  5. 一个项目有两个pom_实现一个Spring Boot Starter超简单,读 Starter 源码也不在话下...

    Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置.不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置 ...

  6. 实现一个 Spring Boot Starter 原来如此简单,读 Starter 源码也不在话下

    我是风筝,公众号「古时的风筝」,一个在程序圈混迹多年,主业 Java,另外 Python.React 也玩儿的 6 的斜杠开发者.现已转行程序员鼓励师 Spring Cloud 系列文章已经完成,可以 ...

  7. 如何使用SpringBoot写一个属于自己的Starter

    (一)概述 SpringBoot以其自动装配的能力被广泛应用,我们在写代码时肯定遇到过很多spring-boot-starter命名的依赖,比如spring-boot-starter-web,在pom ...

  8. (五)Alian 的 Spring Cloud DB Starter(第一个Spring Cloud starter)

    目录 一.创建maven工程 二.maven依赖 三.编码 3.1.配置类 3.2.Ebean封装类 四.配置spring.factories 五.打包发布脚本 六.使用 七.验证 7.1.验证 7. ...

  9. 只需4步,自己搞个 Spring Boot Starter !

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者 | 温安适 来源 | https://my.oschina. ...

  10. 如何手撸一个较为完整的RPC框架

    [文章作者/来源]一个没有追求的技术人/https://sourl.cn/sJ4Brp 缘 起 最近在公司分享了手撸RPC,因此做一个总结. 概 念 篇 RPC 是什么? RPC 称远程过程调用(Re ...

最新文章

  1. LeetCode简单题之拼写单词
  2. 玩转html5画图 - TimeLangoliers - 博客园
  3. python将图像转换为8位单通道_【图像处理】OpenCV系列三十五--- equalizeHist函数详解...
  4. linux生成日志文件,linux实现按天生成日志文件并自动清理
  5. LYNC2013部署系列PART10:后端高可用部署
  6. boost::type_erasure模块convert相关的测试程序
  7. 搭建MSSM框架(Maven+Spring+Spring MVC+MyBatis)
  8. Web的新图像格式WebP
  9. 前端05.js入门之BOM对象与DOM对象。
  10. [翻译] FBLikeLayout
  11. 理工专业单身男终极把妹大法
  12. Promise中then的执行顺序详解
  13. HDU-4515,小Q系列故事——世界上最遥远的距离(日期计算)
  14. Java中beimage_GitHub - beconf/ImageBlurring: Android 中通过 Java 与 JNI 分别进行图片模糊;并且进行比较其运算速度。...
  15. 解决google打开界面就是hao123的问题
  16. 远程服务器 上传公钥,ssh-keygen教程第5章:copy公钥要服务端
  17. English Words(For Computer Science)
  18. 这几天你骑摩拜单车的时候,听到圣诞歌了吗?
  19. 扫描普通二维码进入小程序
  20. ydisk安卓版本_DiskInfo下载-DiskInfo(手机磁盘使用情况)下载v4.9.9 (build 10) 安卓版-西西软件下载...

热门文章

  1. DDR SDRAM内存发展历程
  2. PostgreSQL下载及Windows系统安装步骤
  3. 使用gitee部署静态网页
  4. 深度强化学习(3):策略学习篇
  5. pytorch动态调整学习率之Poly策略
  6. Android P 怎样屏蔽HOME键和RECENT键
  7. 如何提高网页的加载速度 ——DNS优化和代码优化
  8. jp.ne.so_net.ga2.no_ji.jcom.JComException: createInstance() failed HRESULT=0x800401F3L
  9. 大数据工程师要学的编程_每个数据工程师都应了解的ml编程技巧,第2部分
  10. javaweb调用python修改微信运动步数,使用小米运动接口