自定义spring boot starter三部曲之二:实战开发
Posted 程序员欣宸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义spring boot starter三部曲之二:实战开发相关的知识,希望对你有一定的参考价值。
欢迎访问我的GitHub
- 本文是《自定义spring boot starter三部曲》的第二篇,上一篇中我们通过学习spring cloud的starter,对spring boot的starter有了初步了解,也设计好了实战内容,今天就来一起实现;
本章内容概述
- 创建工程customizestarter;
- 创建模块customizeapi;
- 创建模块addservice;
- 创建模块minusservice;
- 创建模块customizeservicestarter;
- 构建工程customizestarter,并安装到本地maven仓库;
- 创建工程customizestartertestdemo;
- 构建工程customizestartertestdemo,得到jar包;
- 启动customizestartertestdemo工程的jar包,并带上一个启动参数,验证支持负数的减法服务;
- 启动customizestartertestdemo工程的jar包,验证不支持服务的减法服务;
源码下载
- 您也可以选择直接从GitHub下载customizestarter和customizestartertestdemo这两个工程的源码,地址和链接信息如下表所示:
名称 | 链接 | 备注 |
---|---|---|
项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本章源码分别在customizestarter和customizestartertestdemo这两个文件夹下,如下图红框所示:
- 接下来开始开发吧;
创建工程customizestarter
- 创建一个名为customizestarter的maven工程,以**spring-boot-starter-parent</font>作为父工程,同时自身又是后续几个模块的父工程,pom.xml内容如下:
<?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>com.bolingcavalry</groupId>
<artifactId>customizestarter</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
<modules>
<!--加法服务-->
<module>addservice</module>
<!--减法服务-->
<module>minusservice</module>
<!--接口和异常定义-->
<module>customizeapi</module>
<!--启动器-->
<module>customizeservicestarter</module>
</modules>
</project>
创建模块customizeapi
- 在工程customizestarter下创建模块customizeapi,这是个java工程,里面是加法和减法服务的接口,和一个业务异常的定义;
- customizeapi的pom.xml内容如下,很简单,只有基本定义:
<?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">
<parent>
<artifactId>customizestarter</artifactId>
<groupId>com.bolingcavalry</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>customizeapi</artifactId>
</project>
- 异常定义类:
package com.bolingcavalry.api.exception;
/**
* @author wilzhao
* @description 执行减法服务时抛出的异常
* @email zq2599@gmail.com
* @time 2018/10/13 14:20
*/
public class MinusException extends Exception
public MinusException(String message)
super(message);
- 加法服务的接口类AddService:
package com.bolingcavalry.api.service;
/**
* @author wilzhao
* @description 加法服务对应的接口
* @email zq2599@gmail.com
* @time 2018/10/13 10:07
*/
public interface AddService
/**
* 普通加法
* @param a
* @param b
* @return
*/
int add(int a, int b);
- 减法服务定义类,注意减法API声明了异常抛出,因为如果已经配置了不支持负数的减法服务,那么被减数如果小于减数就抛出异常:
package com.bolingcavalry.api.service;
import com.bolingcavalry.api.exception.MinusException;
/**
* @author wilzhao
* @description 减法服务
* @email zq2599@gmail.com
* @time 2018/10/13 12:07
*/
public interface MinusService
/**
* 普通减法
* @param minuend 减数
* @param subtraction 被减数
* @return 差
*/
int minus(int minuend, int subtraction) throws MinusException;
创建模块addservice
- 在工程customizestarter下创建模块addservice,这是个java工程,里面包含了加法相服务的实现,pom.xml内容如下,注意由于要实现加法接口,因此需要依赖模块customizeapi:
<?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">
<parent>
<artifactId>customizestarter</artifactId>
<groupId>com.bolingcavalry</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>addservice</artifactId>
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>customizeapi</artifactId>
<version>$project.version</version>
</dependency>
</dependencies>
</project>
- 加法接口的实现类AddServiceImpl很简单,如下:
package com.bolingcavalry.addservice.service.impl;
import com.bolingcavalry.api.service.AddService;
/**
* @author wilzhao
* @description 加法服务的实现
* @email zq2599@gmail.com
* @time 2018/10/13 10:59
*/
public class AddServiceImpl implements AddService
public int add(int a, int b)
return a + b;
创建模块minusservice
- 在工程customizestarter下创建模块minusservice,这是个java工程,里面包含了减法相服务的实现,pom.xml内容如下,注意由于要实现减法接口,因此需要依赖模块customizeapi:
<?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">
<parent>
<artifactId>customizestarter</artifactId>
<groupId>com.bolingcavalry</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>minusservice</artifactId>
<dependencies>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>customizeapi</artifactId>
<version>$project.version</version>
</dependency>
</dependencies>
</project>
- 一共有两个减法接口的实现类,第一个不支持负数结果,如果被减数小于减数就抛出异常MinusException:
package com.bolingcavalry.minusservice.service.impl;
import com.bolingcavalry.api.exception.MinusException;
import com.bolingcavalry.api.service.MinusService;
/**
* @author wilzhao
* @description 减法服务的实现,不支持负数
* @email zq2599@gmail.com
* @time 2018/10/13 14:24
*/
public class MinusServiceNotSupportNegativeImpl implements MinusService
/**
* 减法运算,不支持负数结果,如果被减数小于减数,就跑出MinusException
* @param minuend 被减数
* @param subtraction 减数
* @return
* @throws MinusException
*/
public int minus(int minuend, int subtraction) throws MinusException
if(subtraction>minuend)
throw new MinusException("not support negative!");
return minuend-subtraction;
- 第二个减法接口的实现类支持负数返回:
package com.bolingcavalry.minusservice.service.impl;
import com.bolingcavalry.api.exception.MinusException;
import com.bolingcavalry.api.service.MinusService;
/**
* @author wilzhao
* @description 支持负数结果的减法服务
* @email zq2599@gmail.com
* @time 2018/10/13 14:30
*/
public class MinusServiceSupportNegativeImpl implements MinusService
/**
* 减法实现,支持负数
* @param minuend 减数
* @param subtraction 被减数
* @return
* @throws MinusException
*/
public int minus(int minuend, int subtraction) throws MinusException
return minuend - subtraction;
创建模块customizeservicestarter
- 在工程customizestarter下创建模块customizeservicestarter,这是个java工程,里面需要依赖spring boot配置相关的库,由于要在配置中实例化加法和减法服务的实现,因此customizeapi、addservice、minusservice这些模块都要在pom.xml中声明依赖,如下:
<?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">
<parent>
<artifactId>customizestarter</artifactId>
<groupId>com.bolingcavalry</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>customizeservicestarter</artifactId>
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<!--仅编译时才需要-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>customizeapi</artifactId>
<version>$project.version</version>
</dependency>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>addservice</artifactId>
<version>$project.version</version>
</dependency>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>minusservice</artifactId>
<version>$project.version</version>
</dependency>
</dependencies>
</project>
- 创建配置类CustomizeConfiguration,注意getSupportMinusService和getNotSupportMinusService这两个方法上的注解配置,如果环境变量**com.bolingcavalry.supportnegative</font>存在并且等于true,那么getSupportMinusService方法就返回了MinusService接口的实例,如果当前环境没有MinusService接口的实例,就由getNotSupportMinusService方法就返回一个,并且有会在控制台打印创建了哪种实现:
package com.bolingcavalry.customizeservicestarter;
import com.bolingcavalry.addservice.service.impl.AddServiceImpl;
import com.bolingcavalry.api.service.AddService;
import com.bolingcavalry.api.service.MinusService;
import com.bolingcavalry.minusservice.service.impl.MinusServiceNotSupportNegativeImpl;
import com.bolingcavalry.minusservice.service.impl.MinusServiceSupportNegativeImpl;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author wilzhao
* @description 一句话介绍
* @email zq2599@gmail.com
* @time 2018/10/13 14:36
*/
@Configuration
public class CustomizeConfiguration
@Bean
public AddService getAddService()
System.out.println("create addService");
return new AddServiceImpl();
/**
* 如果配置了com.bolingcavalry.supportnegative=true,
* 就实例化MinusServiceSupportNegativeImpl
* @return
*/
@Bean
@ConditionalOnProperty(prefix="com.bolingcavalry",name = "supportnegative", havingValue = "true")
public MinusService getSupportMinusService()
System.out.println("create minusService support minus");
return new MinusServiceSupportNegativeImpl();
/**
* 如果没有配置com.bolingcavalry.supportnegative=true,
* 就不会实例化MinusServiceSupportNegativeImpl,
* 这里的条件是如果没有MinusService类型的bean,就在此实例化一个
* @return
*/
@Bean
@ConditionalOnMissingBean(MinusService.class)
public MinusService getNotSupportMinusService()
System.out.println("create minusService not support minus");
return new MinusServiceNotSupportNegativeImpl();
- 在src\\main\\resources目录下创建一个目录**META-INF</font>,里面创建一个文件spring.factories,内容是如下,表示如果当前应用支持spring boot的自动配置,就会被spring boot框架实例化并注册到spring容器内:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.bolingcavalry.customizeservicestarter.CustomizeConfiguration
构建工程customizestarter
- 到这里customizestarter工程的编码就结束了,在工程内pom.xml所在目录(也就是customizestarter内的第一层目录),执行以下命令可以编译构建并安装到本地maven仓库:
mvn clean install -Dmaven.test.skip=true -U
- 如果编译构建和安装都成功了,可以看到类似如下输出:
[INFO] Installing C:\\temp\\201810\\07\\customizestarter\\customizeservicestarter\\pom.xml to C:\\Users\\12167\\.m2\\repositor
y\\com\\bolingcavalry\\customizeservicestarter\\0.0.1-SNAPSHOT\\customizeservicestarter-0.0.1-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] customizestarter ................................... SUCCESS [ 0.748 s]
[INFO] customizeapi ....................................... SUCCESS [ 3.266 s]
[INFO] addservice ......................................... SUCCESS [ 0.427 s]
[INFO] minusservice ....................................... SUCCESS [ 0.344 s]
[INFO] customizeservicestarter ............................ SUCCESS [ 0.495 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.954 s
[INFO] Finished at: 2018-10-14T00:17:46+08:00
[INFO] Final Memory: 29M/221M
[INFO] ------------------------------------------------------------------------
- 现在starter已经准备好了,我们做一个spring boot的web应用来验证一下;
创建工程customizestartertestdemo
- 工程customizestartertestdemo是个简单的spring boot应用,pom.xml如下,可见并无特别之处,只是多了customizeservicestarter的依赖:
<?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>com.bolingcavalry</groupId>
<artifactId>customizestartertestdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>customizestartertestdemo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>customizeservicestarter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 开发一个Controller类,用于调用AddService和MinusService对应的服务:
package com.bolingcavalry.customizestartertestdemo.controller;
import com.bolingcavalry.api.exception.MinusException;
import com.bolingcavalry.api.service.AddService;
import com.bolingcavalry.api.service.MinusService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author wilzhao
* @description 调用加法和减法服务的测试类
* @email zq2599@gmail.com
* @time 2018/10/13 16:00
*/
@RestController
public class CalculateController
@Autowired
private AddService addService;
@Autowired
private MinusService minusService;
@RequestMapping(value = "/add/added/add", method = RequestMethod.GET)
public String add(@PathVariable("added") int added, @PathVariable("add") int add)
return added + " 加 " + add + " 等于 : " + addService.add(added, add);
@RequestMapping(value = "/minus/minuend/subtraction", method = RequestMethod.GET)
public String minus(@PathVariable("minuend") int minuend, @PathVariable("subtraction") int subtraction) throws MinusException
return minuend + " 减 " + subtraction + " 等于 : " + minusService.minus(minuend, subtraction);
- 启动类如下:
package com.bolingcavalry.customizestartertestdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CustomizestartertestdemoApplication
public static void main(String[] args)
SpringApplication.run(CustomizestartertestdemoApplication.class, args);
构建工程customizestartertestdemo
- 在customizestartertestdemo工程的pom.xml所在目录下执行以下命令即可构建成功:
mvn clean package -Dmaven.test.skip=true
- 命令执行成功后,即可在target目录下见到customizestartertestdemo-0.0.1-SNAPSHOT.jar文件,如下图:
- 现在编码和构建已经全部完成,我们可以来验证了;
验证支持负数的减法服务
- 在customizeapi模块的CustomizeConfiguration类中,有如下方法和注解:
@Bean
@ConditionalOnProperty(prefix="com.bolingcavalry",name = "supportnegative", havingValue = "true")
public MinusService getSupportMinusService()
System.out.println("create minusService support minus");
return new MinusServiceSupportNegativeImpl();
-
从上述代码可见,只要环境变量"com.bolingcavalry.supportnegative"等于true,注册到spring容器的就是MinusServiceSupportNegativeImpl类的实例;
- customizestartertestdemo-0.0.1-SNAPSHOT.jar文件所在目录下,执行以下命令启动应用:
java -Dcom.bolingcavalry.supportnegative=true -jar customizestartertestdemo-0.0.1-SNAPSHOT.jar
-
在控制台中可以看见**create minusService support minus</font>,表示注册到spring容器的是MinusServiceSupportNegativeImpl类的实例,如下所示:
2018-10-14 12:04:54.233 INFO 16588 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: requestContextFilter to: [/*] create addService create minusService support minus 2018-10-14 12:04:54.845 INFO 16588 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@443b7951: startup date [Sun Oct 14 12:04:50 CST 2018]; root of context hierarchy
- 在浏览器访问http://localhost:8080/minus/1/2,可见返回计算结果为负数:
验证不支持负数的减法服务
-
前面已经分析过,CustomizeConfiguration类的getNotSupportMinusService方法执行的条件是环境变量"com.bolingcavalry.supportnegative"等于true,如果没有这个环境变量,getNotSupportMinusService方法就不会执行,spring容器中就没有MinusService接口的实例;
- CustomizeConfiguration类中,有如下方法和注解:
@Bean
@ConditionalOnMissingBean(MinusService.class)
public MinusService getNotSupportMinusService()
System.out.println("create minusService not support minus");
return new MinusServiceNotSupportNegativeImpl();
-
从上述代码可见,spring容器中如果没有MinusService接口的实例,getNotSupportMinusService方法就会被执行,在spring容器中注册MinusServiceNotSupportNegativeImpl实例;
- 因此接下来的我们启动的应用如果没有环境变量"com.bolingcavalry.supportnegative",就可以使用到不支持负数的减法服务了;
- 停掉之前启动的应用,然后执行以下命令启动应用:
java -jar customizestartertestdemo-0.0.1-SNAPSHOT.jar
- 在控制台中可以看见**create minusService not support minus</font>,表示注册到spring容器的是MinusServiceNotSupportNegativeImpl类的实例,如下所示:
2018-10-14 12:15:05.994 INFO 16608 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: requestContextFilter to: [/*]
create addService
create minusService not support minus
2018-10-14 12:15:06.592 INFO 16608 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@443b7951: startup date [Sun Oct 14 12:15:02 CST 2018]; root of context hierarchy
- 在浏览器访问http://localhost:8080/minus/1/2,由于MinusServiceNotSupportNegativeImpl实例不支持负数减法,会直接抛出异常,如下图:
-
至此,自定义spring boot starter的编码实战就完成了,希望本篇可以给您用来作参考,助您做出自己所需的starter;
- 下一篇我们一起去看看spring boot的源码,对这个高效的扩展功能做更深入的了解;
欢迎关注51CTO博客:程序员欣宸
以上是关于自定义spring boot starter三部曲之二:实战开发的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点#自定义spring boot starter三部曲之三:源码分析spring.factories加载过程
Spring Boot - 手把手教小师妹自定义Spring Boot Starter
企业级spring-boot案例-自定义Spring Boot Starter
Spring Boot---自定义spring boot starter 问题