热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

读懂Springboot自动配置原理必会的javaSPI思想

读懂Springboot必会的javaSPI思想什么是java的SPISPI应用场景JavaSPI规范案例代码创建案例工程什么是java的SPISPI全称ServiceProvi

读懂Springboot必会的java SPI思想

  • 什么是java的SPI
  • SPI 应用场景
  • Java SPI 规范
  • 案例代码
  • 创建案例工程


什么是java的SPI

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。
在这里插入图片描述
Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。

系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。
Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦。

SPI 应用场景

比较常见的例子:

数据库驱动加载接口实现类的加载
JDBC加载不同类型数据库的驱动
日志门面接口实现类加载
SLF4J加载不同提供商的日志实现类
Spring
Spring中大量使用了SPI,比如:对servlet3.0规范对ServletContainerInitializer的实现、自动类型转换Type Conversion SPI(Converter SPI、Formatter SPI)等
Dubbo
Dubbo中也大量使用SPI的方式实现框架的扩展, 不过它对Java提供的原生SPI做了封装,允许用户扩展实现Filter接口

Java SPI 规范

要使用Java SPI,需要遵循如下约定:

1、当服务提供者提供了接口的一种具体实现后,在jar包的META-INF/services目录下创建一个以“接口全限定名”为命名的文件,内容为实现类的全限定名;
2、接口实现类所在的jar包放在主程序的classpath中;
3、主程序通过java.util.ServiceLoder动态装载实现模块,它通过扫描META-INF/services目录下的配置文件找到实现类的全限定名,把类加载到JVM;
4、SPI的实现类必须携带一个不带参数的构造方法;

案例代码
创建案例工程

1.创建父工程
在这里插入图片描述
2. 创建service-common工程
在这里插入图片描述
此工程模块为其他工程的公共的依赖模块,在其中定义PayService接口

public interface PayService {public void pay();
}

  1. 创建ali-pay工程
    在这里插入图片描述
    在pom.xml文件中引入依赖

<dependencies><dependency><groupId>cn.tx.spi</groupId><artifactId>service-common</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>

创建PayService的实现类AliPayService

public class AliPayService implements PayService {public void pay() {System.out.println("支付宝支付");}
}

在resources下创建META-INF.services包
创建cn.tx.service.PayService文件内容如下&#xff1a;指定文件名所示的接口的实现类

cn.tx.impl.AliPayService

4.创建wx-pay工程

在这里插入图片描述
在pom.xml文件中引入依赖

<dependencies><dependency><groupId>cn.tx.spi</groupId><artifactId>service-common</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>

创建PayService的实现类WxPayService

public class WxPayService implements PayService {public void pay() {System.out.println("微信支付");}
}

在resources下创建META-INF.services包
创建cn.tx.service.PayService文件内容如下&#xff1a;指定文件名所示的接口的实现类

cn.tx.impl.WxPayService

5.创建main-pay工程
引入依赖

<dependencies><dependency><groupId>cn.tx.spi</groupId><artifactId>service-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>cn.tx.spi</groupId><artifactId>ali-pay</artifactId><version>1.0-SNAPSHOT</version></dependency><!--<dependency><groupId>cn.tx.spi</groupId><artifactId>wx-pay</artifactId><version>1.0-SNAPSHOT</version></dependency>--></dependencies>

创建测试类

public class Test {public static void main(String[] args) {ServiceLoader<PayService> services &#61; ServiceLoader.load(PayService.class);for (PayService service : services) {service.pay();}}
}

执行测试&#xff1a;我们可以看到我们引入的Ali-pay就能得到AlipayService的实现类实例
在这里插入图片描述
如果我在pom中切换依赖

<dependencies><dependency><groupId>cn.tx.spi</groupId><artifactId>service-common</artifactId><version>1.0-SNAPSHOT</version></dependency><!--<dependency><groupId>cn.tx.spi</groupId><artifactId>ali-pay</artifactId><version>1.0-SNAPSHOT</version></dependency>--><dependency><groupId>cn.tx.spi</groupId><artifactId>wx-pay</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>

再次执行测试&#xff1a;我们可以看到我们引入的wx-pay就能得到WxpayService的实现类实例
在这里插入图片描述
如果两种支付的依赖都引入

<dependencies><dependency><groupId>cn.tx.spi</groupId><artifactId>service-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>cn.tx.spi</groupId><artifactId>ali-pay</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>cn.tx.spi</groupId><artifactId>wx-pay</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>

测试结果
在这里插入图片描述
使用Java SPI机制的优势是实现解耦&#xff0c;使得第三方服务模块的装配控制的逻辑与调用者的业务代码分离&#xff0c;而不是耦合在一起。应用程序可以根据实际业务情况启用框架扩展或替换框架组件。
Springboot的原理即是使用期原理来做的自动配置。
源码获取和更多内容可以加Q群264572737
在这里插入图片描述
直接群中找到我即可。


推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
  • python3 logging
    python3logginghttps:docs.python.org3.5librarylogging.html,先3.5是因为我当前的python版本是3.5之所 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • JVM:33 如何查看JVM的Full GC日志
    1.示例代码packagecom.webcode;publicclassDemo4{publicstaticvoidmain(String[]args){byte[]arr ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
author-avatar
铁打的岳小野
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有