当前位置 : 主页 > 编程语言 > java >

自定义spring boot starter三部曲之二:实战开发

来源:互联网 收集:自由互联 发布时间:2022-07-17
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本文是《自定义spring boot starter三部曲》的第二篇,上一篇中我们通过学习spring cloud的s

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

  • 本文是《自定义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这两个文件夹下,如下图红框所示:

    image.png

    • 接下来开始开发吧;

    创建工程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文件,如下图:

    image.png

    • 现在编码和构建已经全部完成,我们可以来验证了;

    验证支持负数的减法服务

    • 在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,可见返回计算结果为负数:

    image.png

    验证不支持负数的减法服务

    • 前面已经分析过,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实例不支持负数减法,会直接抛出异常,如下图:

    image.png

    • 至此,自定义spring boot starter的编码实战就完成了,希望本篇可以给您用来作参考,助您做出自己所需的starter;

    • 下一篇我们一起去看看spring boot的源码,对这个高效的扩展功能做更深入的了解;

    欢迎关注51CTO博客:程序员欣宸

    学习路上,你不孤单,欣宸原创一路相伴...

    上一篇:Java:面向程序对象设计
    下一篇:没有了
    网友评论