【SpringBoot】编写一个自己的Starter
一、什么是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文件
- <?xml version="1.0" encoding="UTF-8"?>
- <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>cn.sp</groupId>
- <artifactId>example-spring-boot-starter</artifactId>
- <version>1.0-SNAPSHOT</version>
- <properties>
- <spring-boot.version>2.1.5.RELEASE</spring-boot.version>
- </properties>
- <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>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <!-- Import dependency management from Spring Boot -->
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-dependencies</artifactId>
- <version>${spring-boot.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
- </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编写自动配置类(重点)
- package cn.sp.autoconfigure;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
- import org.springframework.boot.context.properties.EnableConfigurationProperties;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- /**
- * Created by 2YSP on 2019/5/22.
- */
- @Configuration
- @ConditionalOnClass(StarterService.class)
- //@ConditionalOnProperty(prefix = "cn.sp",value = "enable",matchIfMissing = true)
- @EnableConfigurationProperties(StarterServiceProperties.class)
- public class StarterAutoConfigure {
- @Autowired
- private StarterServiceProperties properties;
- @Bean
- @ConditionalOnMissingBean
- @ConditionalOnProperty(prefix = "cn.sp",value = "enabled",havingValue = "true")
- StarterService starterService(){
- return new StarterService(properties.getConfig());
- }
- }
说下这几个注解的作用:
- @ConditionalOnClass:当classpath下发现该类的情况下进行自动配置。
- @EnableConfigurationProperties:使使用 @ConfigurationProperties 注解的类生效。具体可以参考https://www.jianshu.com/p/7f54da1cb2eb
- @ConditionalOnMissingBean:当Spring上下文中不存在该Bean时生效。
- @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害我折腾了半天。
三、测试
- 执行mvn install命令打包到本地
- 在另外一个项目添加依赖
<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
- 编写测试类并启动
@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]);}}}
- 运行结果如下则表示成功。
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相关推荐
- 编写一个springBoot接口
目标:编写一个springBoot接口 要求:做一个有分页,有排序的模糊查询接口 步骤 第一步 先在dao层的Mapper目录下完成接口的编写,由于查询到的结果是很多条数据,所以返回类型List& ...
- 如何使用SpringBoot写一个属于自己的Starter
(一)概述 SpringBoot以其自动装配的能力被广泛应用,我们在写代码时肯定遇到过很多spring-boot-starter命名的依赖,比如spring-boot-starter-web,在pom ...
- 玩转 SpringBoot 2.x 之自定义Starter依赖
前言 SpringBoot 核心功能之一就是 starter 依赖也叫起步依赖,他默认提供了 spring-boot-starter-web.spring-boot-starter-logging.s ...
- 实现一个 Spring Boot Starter 原来如此简单,读 Starter 源码也不在话下
我是风筝,公众号「古时的风筝」,一个在程序圈混迹多年,主业 Java,另外 Python.React 也玩儿的 6 的斜杠开发者.现已转行程序员鼓励师 Spring Cloud 系列文章已经完成,可以 ...
- 基于SpringBoot开发一个Restful服务,实现增删改查功能
点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者:虚无境 cnblogs.com/xuwujing/p/8260935.html 前言 在去 ...
- SpringBoot 编写ajax可以访问的接口
SpringBoot最近也是刚刚开始看,发现有和平时用到的SpringMVC有很多的不同,首选配置简单的很多,并且可以在tomcat上面运行,那么SpringBoot是一种类似于微服务,那么编写接口如 ...
- 一个项目有两个pom_实现一个Spring Boot Starter超简单,读 Starter 源码也不在话下...
Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置.不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置 ...
- SpringBoot编写HelloWorld-new
我们通过刚刚创建的SpringBoot项目,来完成一个HelloWorld,首先打开我们的项目,我们看一下项目中的pom文件,我们已经添加一个WEB版的坐标,那么也就意味着,我们在做WEB的常用一些j ...
- 使用SpringBoot搭建一个简单的webSocket服务
前言 个人地址:使用SpringBoot搭建一个简单的webSocket服务 什么是WebSocket? WebSocket是一个HTML5新增的协议,它的目的在浏览器和服务器之间建立一个不受限的双向 ...
最新文章
- H5的学习从0到1-H5的实体(14)
- java 学习 --------接口概念
- java单例设计模式
- 如何在Eclipse和Android Studio中导入library project
- mac mysql-python 失败_MAC OS安装MySQL-python总是失败,请帮忙看看什么原因?
- 基于JAVA+Servlet+JSP+MYSQL的牙科诊所管理系统
- docker $PWD路径_Docker 数据持久化
- 微信如何做好服务器,如何用免费服务器做微信JS开发
- c 实现走迷宫流程图_C语言实现一个走迷宫小游戏(深度优先算法)
- 安卓投屏大师TC DS如何把手机声音传输到电脑教程
- Robin:SEO从业者打造个人品牌的八个建议,白杨SEO个人品牌实战举例
- TP开发的源码或素材付费下载站网站源码+整体不错
- 手把手教你买基金----读书笔记
- 样条曲线长度--数值积分
- 漫谈autoencoder:降噪自编码器/稀疏自编码器/栈式自编码器(含tensorflow实现)
- 大数据产品研究 - Presto简介
- CAP 原理和分布式矩阵的应用
- Android6.0修改以太网IP
- 三面阿里,有惊无险成功拿到offer定级P7,只能说是真的难
- 医疗器械网电源部分使用一个保险丝还是两个保险丝?