栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java SPI机制使用及实际案例分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java SPI机制使用及实际案例分析

Java SPI机制应用场景及案例分析
  • 前言
  • 一、什么是SPI机制?
  • 二、实现方式及使用场景
    • 1. 接口全限定文件名方式
        • 使用场景一:
        • 结合场景一分析:
    • 2.spring.factories方式
          • 使用场景二
        • 结合场景二分析:
  • 总结


前言

在之前的JVM 分析系列之类加载提到过 Java SPI 机制,主要是类加载器反双亲委派的实现(第三方包不在指定jdk路径,一般类加载器无法加载,需要特殊的ContextClassLoader加载以便使用)。本次将对 SPI机制进行详解,并结合案例介绍其在实际场景中具体使用。


提示:以下是本篇文章正文内容,案例仅供对比参考

一、什么是SPI机制?
  • SPI(全称:Service Provider Interface),是jdk内置的一种服务提供发现接口机制,旨在由第三方服务实现或扩展为组件,方便开发人员快速集成指定扩展组件满足指定的需求。这对于应用或平台扩展来说,无疑是一种成本较低、动态灵活的方案。
  • SPI机制调度过程(业务调用方可根据加载的扩展实现类实现功能)
二、实现方式及使用场景

鉴于目前实际项目涉及范围,总结出的常见应用场景。

1. 接口全限定文件名方式
  • 即在resource文件下创建META/services/目录,并在此目录下新建文件,文件名称为接口类权限定文件名,如 com.lgy.spidemo.serviceway.SpiService。(不好理解就是接口类的package地址 + 接口类名)
使用场景一:
  • 场景描述:不同部门类型的员工需要从不同的考勤应用获取出勤信息,如职能部门仅拉取钉钉考勤,业务部门需要拉取钉钉考勤的基础上再结合自研考勤模块数据汇总出勤结果。
  • 实现方式:抽象通用拉取考勤接口,定义不同部门人员考勤统计实现类。
  • 直接上代码:
package com.lgy.spidemo.serviceway;


public interface AttendanceService {
    void pullAttendanceInfos();
}


public class FunctionAttendanceServiceImpl implements AttendanceService  {
    @Override
    public void pullAttendanceInfos() {
        System.out.println(" FunctionAttendanceService implements ...");
        // 逻辑忽略
    }
}


public class SaleAttendanceServiceImpl implements AttendanceService  {
    @Override
    public void pullAttendanceInfos() {
        System.out.println(" SaleAttendanceService implements ...");
        // 逻辑忽略
    }
}


public class AttendanceServiceTest {
    public static void main(String[] args) {
        ServiceLoader services =
        		 ServiceLoader.load(AttendanceService.class);
        // 省略判断人员部门类型逻辑
        // 测试输出结果,展示实现接口已加载
        for (AttendanceService service : services) {
            service.pullAttendanceInfos();
        }
    }
}
  • 测试结果如下
 FunctionAttendanceService implements ...
 SaleAttendanceService implements ...
  • 实现类不要标注任何注解,不然Spring在初始化过程中扫描并加载,无法测试。
结合场景一分析:
  • 此场景可以通过自定义实现类很快实现业务需求,以配置的方式比较灵活的管理场景所需,对出快速迭代过程有很好的的管理帮助。
  • 考虑公司组织架构比较复杂,部门职责分的比较细,后续扩展几率比较大,比如职能部门行政类和运营类标准细分,很可能会增加除了考勤之外的各种考核指标等,借鉴此方案可能简单实现并比较方便集成,使得业务间减少依赖,实现解耦的设计模式,因此个人是比较偏向用此方案。
  • 其它应用:如项目中常用的日志也是采用SPI机制,常见的common-logging的LogFatory就是标准SPI接口,有兴趣的可以自行研究。
2.spring.factories方式
  • 和上面一样,需要在resource文件下创建META/services/目录,并在此目录下新建文件,区别在于文件名为 spring.factories。
使用场景二
  • 场景描述:针对于不同的开发端使用习惯展示不同的接口文档,比如APP端习惯于Swagger,JAVA端喜欢dateway风格,就在不同实例展示不同接口文档。此场景是我臆想出来。
  • 实现方式:构建两种版本的jar包,比如 1.0.0-swagger 、2.0.0-dataway,再对应的包内配置spring.factories内的config配置类。
  • 代码如下:
package com.lgy.spidemo.factoriesway;

import org.springframework.boot.autoconfigure.AutoConfigurationImportEvent;
import org.springframework.boot.autoconfigure.AutoConfigurationImportListener;


public class SwaggetAutoConfiguration {
	public SwaggetAutoConfiguration() {
        System.out.println(" SwaggetAutoConfiguration init ...");
    }
	// 配置内容省略
}


public class DataWayAutoConfiguration {
	public DataWayAutoConfiguration() {
        System.out.println(" DataWayAutoConfiguration init ...");
    }
	// 配置内容省略
}


  • 根据spring.factories内配置的类,在springboot启动初始化过程中会自动加载对应的配置,实现所需的接口文档。
结合场景二分析:
  • spring.factories实现机制与上述方式一致,只是实现方式不同,本质目的是通过抽象化类的方式,实现解耦,最终便于扩展
  • 其它使用场景:如spring-boot-autoconfigure-x.x.x.RELEASE.jar,就是通过此方式完成初始化加载。

总结
  • 本次讲解的两种方式均是基于SPI机制,可见是多么受开发追捧。当然,还有很多种实现方式,我个人觉得最主要的还是能够在自己的掌控范围内去使用,毕竟有问题可以通过自己的学习理解去解决。
  • 最后说一句,没有更好的技术知识,只有更适合的技术应用,结合实际,检出真理。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1009244.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号