一、什么是Starter?

在开发过程中我们就经常使用到各种starter,比如mybatis-spring-boot-starter,只需要进行简单的配置即可使用,就像一个插件非常方便。这也是SpringBoot非常重要的一个特性——自动化配置。

二、实现

2.1创建一个maven项目并配置pom.xml

命名规范: Spring官方的Starter命名格式一般是spring-boot-starter-{name},比如spring-boot-starter-web 。而非官方的,官方建议artifactId命名应该遵循 {name}-spring-boot-starter的格式,如example-spring-boot-starter。

pom文件

  1. <?xml version="1.0" encoding="UTF-8"?>


  2. <project xmlns="http://maven.apache.org/POM/4.0.0" 

  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 

  5. <modelVersion>4.0.0</modelVersion> 


  6. <groupId>cn.sp</groupId> 

  7. <artifactId>example-spring-boot-starter</artifactId> 

  8. <version>1.0-SNAPSHOT</version> 


  9. <properties> 

  10. <spring-boot.version>2.1.5.RELEASE</spring-boot.version> 

  11. </properties> 


  12. <dependencies> 

  13. <dependency> 

  14. <groupId>org.springframework.boot</groupId> 

  15. <artifactId>spring-boot-configuration-processor</artifactId> 

  16. <optional>true</optional> 

  17. </dependency> 


  18. <dependency> 

  19. <groupId>org.springframework.boot</groupId> 

  20. <artifactId>spring-boot-autoconfigure</artifactId> 

  21. </dependency> 

  22. </dependencies> 



  23. <dependencyManagement> 

  24. <dependencies> 

  25. <dependency> 

  26. <!-- Import dependency management from Spring Boot --> 

  27. <groupId>org.springframework.boot</groupId> 

  28. <artifactId>spring-boot-dependencies</artifactId> 

  29. <version>${spring-boot.version}</version> 

  30. <type>pom</type> 

  31. <scope>import</scope> 

  32. </dependency> 

  33. </dependencies> 

  34. </dependencyManagement> 


  35. </project> 

spring-boot-configuration-processor 的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给IDE使用,ctlr+鼠标左键点击配置文件(如application.properties)上相关配置属性,即可跳转到配置此属性的类中。

我们要实现的一个小功能是读取配置文件上cn.sp.config的字符串,然后按照给定的分隔符进行分割。

2.2编写配置文件读取类

@ConfigurationProperties(prefix = "cn.sp")
public class StarterServiceProperties {private String config;public String getConfig() {return config;}public void setConfig(String config) {this.config = config;}
}

2.3编写Service

public class StarterService {private String config;public StarterService(String config){this.config = config;}public String[] split(String separatorChar){return this.config.split(separatorChar);}
}

2.4编写自动配置类(重点)

  1. package cn.sp.autoconfigure;



  2. import org.springframework.beans.factory.annotation.Autowired; 

  3. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 

  4. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 

  5. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 

  6. import org.springframework.boot.context.properties.EnableConfigurationProperties; 

  7. import org.springframework.context.annotation.Bean; 

  8. import org.springframework.context.annotation.Configuration; 


  9. /** 

  10. * Created by 2YSP on 2019/5/22. 

  11. */ 

  12. @Configuration 

  13. @ConditionalOnClass(StarterService.class) 

  14. //@ConditionalOnProperty(prefix = "cn.sp",value = "enable",matchIfMissing = true) 

  15. @EnableConfigurationProperties(StarterServiceProperties.class) 

  16. public class StarterAutoConfigure { 


  17. @Autowired 

  18. private StarterServiceProperties properties; 


  19. @Bean 

  20. @ConditionalOnMissingBean 

  21. @ConditionalOnProperty(prefix = "cn.sp",value = "enabled",havingValue = "true") 

  22. StarterService starterService(){ 

  23. return new StarterService(properties.getConfig()); 







说下这几个注解的作用:

  1. @ConditionalOnClass:当classpath下发现该类的情况下进行自动配置。
  2. @EnableConfigurationProperties:使使用 @ConfigurationProperties 注解的类生效。具体可以参考https://www.jianshu.com/p/7f54da1cb2eb
  3. @ConditionalOnMissingBean:当Spring上下文中不存在该Bean时生效。
  4. @ConditionalOnProperty(prefix = "cn.sp",value = "enabled",havingValue = "true"),当配置文件中cn.sp.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项目的条件下

2.5创建spring.factories

在 resources/META-INF/ 文件夹下创建spring.factories文件,内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.sp.autoconfigure.StarterAutoConfigure

右边的就是自动配置类的类路径,注意单词别打错了,我就是META-INF打成了MATA-INF害我折腾了半天。

三、测试

  1. 执行mvn install命令打包到本地
  2. 在另外一个项目添加依赖
<dependency><groupId>cn.sp</groupId><artifactId>example-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version></dependency>

然后可以看到jar包的结构图如下:

3. 在application.properties文件添加如下内容

cn.sp.enabled=true
cn.sp.config=fdafdf,ss1,DSDS,DDD

  1. 编写测试类并启动
@RunWith(SpringRunner.class)
@SpringBootTest
public class MySpringbootApplicationTests {@AutowiredStarterService starterService;@Testpublic void contextLoads() {String[] strings = starterService.split(",");for (int i = 0; i < strings.length; i++) {System.out.println(strings[i]);}}}

  1. 运行结果如下则表示成功。

2019-05-23 10:41:49.219 [main] INFO cn.sp.MySpringbootApplicationTests - Started MySpringbootApplicationTests in 10.977 seconds (JVM running for 13.035)
fdafdf
ss1
DSDS
DDD

2019-05-23 10:41:52.411 [Thread-4] INFO o.s.w.c.s.GenericWebApplicationContext - Closing org.springframework.web.context.support.GenericWebApplicationContext@51f49060: startup date [Thu May 23 10:41:38 CST 2019]; root of context hierarchy

四、原理

1.在应用程序启动过程中,Spring Boot使用SpringFactoriesLoader类加载器查找org.springframework.boot.autoconfigure.EnableAutoConfiguration关键字对应的Java配置文件。Spring Boot会遍历在各个jar包中META-INF目录下的spring.factories文件,构建成一个配置文件链表。
2.根据spring.factories配置加载AutoConfigure类
3.根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context中。
注意: Spring Boot的starter在编译时不需要依赖Spring Boot的库。
代码地址:https://github.com/2YSP/example-spring-boot-starter
参考:
https://juejin.im/entry/58d37630570c350058c2c15c
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html

转载于:https://www.cnblogs.com/2YSP/p/10911166.html

【SpringBoot】编写一个自己的Starter相关推荐

  1. 编写一个springBoot接口

    目标:编写一个springBoot接口 要求:做一个有分页,有排序的模糊查询接口 步骤 第一步 ​ 先在dao层的Mapper目录下完成接口的编写,由于查询到的结果是很多条数据,所以返回类型List& ...

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

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

  3. 玩转 SpringBoot 2.x 之自定义Starter依赖

    前言 SpringBoot 核心功能之一就是 starter 依赖也叫起步依赖,他默认提供了 spring-boot-starter-web.spring-boot-starter-logging.s ...

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

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

  5. 基于SpringBoot开发一个Restful服务,实现增删改查功能

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者:虚无境 cnblogs.com/xuwujing/p/8260935.html 前言 在去 ...

  6. SpringBoot 编写ajax可以访问的接口

    SpringBoot最近也是刚刚开始看,发现有和平时用到的SpringMVC有很多的不同,首选配置简单的很多,并且可以在tomcat上面运行,那么SpringBoot是一种类似于微服务,那么编写接口如 ...

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

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

  8. SpringBoot编写HelloWorld-new

    我们通过刚刚创建的SpringBoot项目,来完成一个HelloWorld,首先打开我们的项目,我们看一下项目中的pom文件,我们已经添加一个WEB版的坐标,那么也就意味着,我们在做WEB的常用一些j ...

  9. 使用SpringBoot搭建一个简单的webSocket服务

    前言 个人地址:使用SpringBoot搭建一个简单的webSocket服务 什么是WebSocket? WebSocket是一个HTML5新增的协议,它的目的在浏览器和服务器之间建立一个不受限的双向 ...

最新文章

  1. H5的学习从0到1-H5的实体(14)
  2. java 学习 --------接口概念
  3. java单例设计模式
  4. 如何在Eclipse和Android Studio中导入library project
  5. mac mysql-python 失败_MAC OS安装MySQL-python总是失败,请帮忙看看什么原因?
  6. 基于JAVA+Servlet+JSP+MYSQL的牙科诊所管理系统
  7. docker $PWD路径_Docker 数据持久化
  8. 微信如何做好服务器,如何用免费服务器做微信JS开发
  9. c 实现走迷宫流程图_C语言实现一个走迷宫小游戏(深度优先算法)
  10. 安卓投屏大师TC DS如何把手机声音传输到电脑教程
  11. Robin:SEO从业者打造个人品牌的八个建议,白杨SEO个人品牌实战举例
  12. TP开发的源码或素材付费下载站网站源码+整体不错
  13. 手把手教你买基金----读书笔记
  14. 样条曲线长度--数值积分
  15. 漫谈autoencoder:降噪自编码器/稀疏自编码器/栈式自编码器(含tensorflow实现)
  16. 大数据产品研究 - Presto简介
  17. CAP 原理和分布式矩阵的应用
  18. Android6.0修改以太网IP
  19. 三面阿里,有惊无险成功拿到offer定级P7,只能说是真的难
  20. 医疗器械网电源部分使用一个保险丝还是两个保险丝?

热门文章

  1. JVM源码—教你傻瓜式编译openjdk7
  2. Intellij Idea/Webstorm/Phpstorm 的高效快捷键
  3. 科研人员的办公室是怎样的?
  4. Hadoop pipes编程
  5. GitHub上一些有用的Repositories
  6. 我的C++学习历程(old)
  7. Deep Learning论文笔记之(六)Multi-Stage多级架构分析
  8. 数字图像处理:第十八章 彩色图象处理
  9. Filesystem has errors解决办法
  10. 让DB2数据库更牢靠