Java SPI及Demo

首先交代下背景,何爲Java SPI?

   SPI 全稱爲 (Service Provider Interface) ,是JDK內置的一種服務提供發現機制。java

爲何須要SPI? mysql

     咱們的現代系統愈來愈龐大,若是設計架構有問題,就可能牽一髮而動全身,在面向對象中咱們推薦基於接口編程,模塊之間基於接口編程,這樣的好處顯而易見,不在代碼中進行硬編碼,不一樣的實現者按照接口規範實現本身內部操做,而後在使用的時候再根據 SPI 的規範去獲取對應的服務提供者的服務實現。經過 SPI 服務加載機制進行服務的註冊和發現,能夠有效的避免在代碼中將服務提供者寫死。從而能夠基於接口編程,實現模塊間的解耦。git

SPI機制約定:github

   1.在 META-INF/services/ 目錄中建立以接口全限定名命名的文件,該文件內容爲API具體實     現類的全限定名 sql

   2.使用 ServiceLoader 類動態加載 META-INF 中的實現類  apache

   3.如 SPI 的實現類爲 Jar 則須要放在主程序 ClassPath 中  編程

   4.API 具體實現類必須有一個不帶參數的構造方法  bash

  如圖:架構


 如今已經被使用的案例: maven

  • common-logging Apache最先提供的日誌的門面接口。只有接口,沒有實現。具體方 案由各提供商實現, 發現日誌提供商是經過掃描 META- INF/services/org.apache.commons.logging.LogFactory配置文件,經過讀取該文 件的內容 找到日誌提工商實現類。只要咱們的日誌實現裏包含了這個文件,並在文件裏 制定LogFactory工廠接口的實現類便可。 
  • JDBC jdbc4.0之前, 開發人員還須要基於Class.forName("xxx")的方式來裝載驅動。 建立鏈接: DriverManage.getConnection()中,有Connection con = aDriver.driver.connect(url, info); driver成員變量,是java.sql.Driver接口,Java對外公開的一個加載驅動接口,Java並未實現,至於實現這個接口由各個Jdbc廠商去實現。 如MySQL,mysql-connector-java-5.1.38.jar包下面META-INF.services包下有個java.sql.Driver文件打開文件有下面兩行 com.mysql.jdbc.Driver com.mysql.fabric.jdbc.FabricMySQLDriver     

示例Demo:

  1.     建立maven項目
  2.    目錄以下:
      


  3. 代碼
    OrderService.java

    package com.demo.spi.service;
    
    public interface OrderService {
        int getOrderCountById(int id);
    }
    複製代碼

      CustomerOrderServiceImpl.java

package com.demo.spi.impl;

import com.demo.spi.service.OrderService;

public class CustomerOrderServiceImpl implements OrderService {

    public int getOrderCountById(int id) {
        System.out.println("cutomer order count is 10");
        return 10;
    }

}
複製代碼

       AgencyOrderServiceImpl.java

package com.demo.spi.impl;

import com.demo.spi.service.OrderService;

public class AgencyOrderServiceImpl implements OrderService {

    public int getOrderCountById(int id) {
        System.out.println("agency order count is 20");
        return 20;
    }

}
複製代碼

META-INF下文件名:com.demo.spi.service.OrderService,文件內容:

com.demo.spi.impl.AgencyOrderServiceImpl
com.demo.spi.impl.CustomerOrderServiceImpl複製代碼

4.新建測試項目java project



代碼github地址:https://github.com/HuoMoreMore/demo-spi

運行main方法以前咱們須要將第一個項目進行打包 jar 依賴到第二個java 項目中來,完成以後點擊run,能夠看到打印出了,咱們在項目1 中的兩個serviceImpl方法的輸出,也就是說ServiceLoader 動態的經過jar中的配置找到了 項目1中的實現類而且把他記載到了內存中,咱們就能夠直接調用項目1中提供的兩個實現類,而且正確輸出。

若是有須要瞭解ServiceLoader源碼的朋友能夠參考:

https://www.jianshu.com/p/a6073e9f8cb4

相關文章
相關標籤/搜索