zoukankan      html  css  js  c++  java
  • API/SPI可扩展设计原则(转)

    写本篇主要是用来后面写一篇可扩展性软件设计打好基础(苦于找不到一篇关于API/SPI的好文章,只好自己写一个,欢迎指教)。 
    概念: 
    API:API(Application Programming Interface)表示应用程序编程接口 
    SPI:SPI(Service Provider Interface)表示服务提供商接口 
    API与SPI的关系 
    框架提供API及其实现,框架在实现过程中提供SPI回调机制。SPI是框架的扩展点。如果使用框架方要扩展框架,可以自己实现SPI并注入框架,于是框架使用方其实也是一个服务提供商。 

    SPI实现有两种方式,一种是第三方提供实现,另一种是应用自身自己提供实现 
    看一下API/SPI关系图1,第三方提供商实现了SPI,应用引入第三方提供商的第三方库 

    举例 
    java中JDBC是一个编程接口,而Driver是一个SPI,同时不同数据库厂商会提供Driver的实现。应用中要使用JDBC编程接口时需要引入第三方数据库厂商驱动包,第三方厂商提供的驱动包其实就是SPI的实现。 

    看一下API/SPI关系图1,应用自身为了扩展框架自己实现了SPI,直接在自己的应用包里实现SPI 

    举例 
    我写了一个RenderAPI用来渲染vm模板, 渲染逻辑过程中会默认引入PullTool让vm中可以使用,如DateUtil,StringUtil等。应该可能想引入自己的业务PullTool,如MoneyTool等。于是我可以在RenderAPI接口的实现里,读取PullToolFacotry这个SPI,从这个SPI返回的PullTool加入到渲染引擎里。PullToolFacotry接口里就一个方法public Map<String PullTool> getPullTools();应用端可以写个类叫BusinessPullToolFactoryImpl实现PullToolFactory,把自己想要加入的PullTool返回即可。 

    框架如何发现SPI?
     
    框架可以使用java提供的java.util.ServiceLoader类得到SPI的实现。 
    如ServiceLoader<PullToolFactory> pullToolFactorys     = ServiceLoader.load(PullToolFactory.class); 

    应用或第三方提供商如何注入SPI实现? 
    应用或第三方包在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类的完全限定名。而当框架调用ServiceLoader.load(PullToolFactory.class),就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成SPI实现的注入。 

    总结: 
    可以想象,使用SPI设计,框架可以很容易引入扩展点,同时应用要扩展框架逻辑也很容易实现。框架可扩展设计可以基于这个原则进行设计扩展点。 
  • 相关阅读:
    面向领域的微服务架构
    java常用工具类
    java字节码解析
    详解 Java 内部类
    MongoDB配置教程
    oracle18c相关
    VBS编辑文件夹下所有excel文档
    oracle新增主键
    sqlldr加载字符问题
    ora-00257
  • 原文地址:https://www.cnblogs.com/yuhuameng/p/7766752.html
Copyright © 2011-2022 走看看