Java SPI機制 、Android組件化跨模塊調(diào)用

1、Java SPI機制 ServiceLoader的基本使用

  • Java SPI 實際上是“基于接口的編程+策略模式+配置文件”組合實現(xiàn)的動態(tài)加載機制,
    提供了通過interface尋找implement的方法。類似于IOC的思想,將裝配的控制權(quán)移到程序之外,從而實現(xiàn)解耦。

    Java SPI機制

  • 場景:比如兩個module,app依賴basic_live,但這時basic_live又用到了app模塊中的服務(wù)。
    源碼GitHub

2、方式一

  • 在調(diào)用module中創(chuàng)建一個接口文件ContentService
  • 在具體實現(xiàn)的module中的main目錄(Java同級)下建立resources/META-INF/services/,因為ServiceLoader中會訪問到(查看ServiceLoader.PREFIX)
  • 在services文件夾中創(chuàng)建文件,以接口全名命名
  • 在具體實現(xiàn)的module中創(chuàng)建類來實現(xiàn)接口功能ContentServiceImpl,然后把全類名填到上面創(chuàng)建的文件中

3、方式二

  • 在方式一中,不僅要創(chuàng)建各種路徑、文件,容易寫錯,所以Google發(fā)布了一個庫autoservice幫助大家

  • 在具體實現(xiàn)module中添加依賴,kotlin的可以用kpt

  • implementation 'com.google.auto.service:auto-service:1.0.1'
    annotationProcessor 'com.google.auto.service:auto-service:1.0.1'
    
    kapt 'com.google.auto.service:auto-service:1.0.1'
    
  • 實現(xiàn)接口,并加上@AutoService

  • @AutoService(ContentService.class)
    public class ContentServiceImpl implements ContentService {
          @Override
          public String getTitle() {
               return "the title from app module";
           }
     }
    

4、使用

  • 在ServiceFactory中加了緩存,通過ContentService service = ServiceFactory.getInstance().getService(ContentService.class)獲取

  • public class ServiceFactory {
    
      private static class SingleTonHolder {
          private static final ServiceFactory INSTANCE = new ServiceFactory();
      }
    
      public static ServiceFactory getInstance() {
          return SingleTonHolder.INSTANCE;
      }
      private final ArrayMap<Class, ServiceLoader> loaderMap = new ArrayMap<>();
      private final ArrayMap<Class, Object> serviceMap = new ArrayMap<>();
      private ServiceFactory() {
    
      }
      @Nullable
      public <T> T getService(Class<T> clazz) {
          Object o = serviceMap.get(clazz);
          if (o != null && isInterface(o.getClass(),clazz.getName())) {
              return (T) o;
          }
          ServiceLoader serviceLoader = loaderMap.get(clazz);
          if (serviceLoader == null) {
              serviceLoader = ServiceLoader.load(clazz);
              loaderMap.put(clazz, serviceLoader);
          }
          if (serviceLoader != null && serviceLoader.iterator().hasNext()) {
              T next = (T) serviceLoader.iterator().next();
              serviceMap.put(clazz, next);
              return next;
          }
          return null;
      }
      public boolean isInterface(Class c, String szInterface) {
          Class[] face = c.getInterfaces();
          for (Class aClass : face) {
              if (aClass.getName().equals(szInterface)) {
                  return true;
              } else {
                  Class[] face1 = aClass.getInterfaces();
                  for (Class value : face1) {
                      if (value.getName().equals(szInterface)) {
                          return true;
                      } else if (isInterface(value, szInterface)) {
                          return true;
                      }
                  }
              }
          }
          if (null != c.getSuperclass()) {
              return isInterface(c.getSuperclass(), szInterface);
          }
          return false;
      }
    }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容