跳转至

时间: 2018/9/14 15:32:32

参考:

  1. java.util.ServiceLoader

ServiceLoader#

简介#

服务加载工具类,从 META-INF/services/ 目录查找接口的实现信息,然后初始化接口的实现类,拿到具体的实例化之后的对象,之后使用接口定义的服务。

源码解析#

内部字段#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    # 服务提供类配置文件     
    private static final String PREFIX = "META-INF/services/";
    # 服务接口
    private final Class<S> service
    # 类加载器
    private final ClassLoader loader;
    # 访问控制
    private final AccessControlContext acc;
    # 服务接口实现者提供列表
    private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
    # 懒加载实现,需要服务的时候再加载
    private LazyIterator lookupIterator;

加载过程:#

  1. 调用加载方法,创建 ServiceLoader 对象

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    ServiceLoader<Driver> drivers = ServiceLoader.load(Driver.class);
    
    public static <S> ServiceLoader<S> load(Class<S> service) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        return ServiceLoader.load(service, cl);
    }
    
    public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader){
        return new ServiceLoader<>(service, loader);
    }
    
  2. ServiceLoader 创建过程

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    private ServiceLoader(Class<S> svc, ClassLoader cl) {
        # 验证Service 接口、类加载器判断或初始化、访问控制器判断或初始化
        service = Objects.requireNonNull(svc, "Service interface cannot be null");
        loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
        acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
        //重接加载接口定义
        reload();
    }
    
    //重新加载接口提供者信息
    public void reload() {
        providers.clear();
        # 初始化懒加载器
        lookupIterator = new LazyIterator(service, loader);
    }
    
    1. 获取接口提供者

      初始化ServiceLoader#

      ServiceLoader drivers = ServiceLoader.load(Driver.class);

      获取迭代器, ServiceLoader 实现 Iterable 接口#

      Iterator driverIterator = drivers.iterator(); while (driverIterator.hasNext()) { System.out.println(driverIterator.next().getClass().getName()); }

      drivers.iterator()(ServiceLoader.iterator() 方法实现)#

      public Iterator iterator() { return new Iterator() { // 使用外部类的 providers 初始化 knownProviders Iterator> knownProviders = providers.entrySet().iterator();

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
          public boolean hasNext() {
              if (knownProviders.hasNext()){
                  return true;
              }   
              return lookupIterator.hasNext();
          }
      
          public S next() {
              if (knownProviders.hasNext()){
                  return knownProviders.next().getValue();
              }
              return lookupIterator.next();
          }
      
          public void remove() {
              throw new UnsupportedOperationException();
          }
      
      };
      

      } 4. lookupIterator (LazyIterator) 实现解析:

      字段#

      Class service; //服务接口 ClassLoader loader; //类加载器 Enumeration configs = null; //所有提供者配置信息 Iterator pending = null; //服务提供者迭代器 String nextName = null; //下一个服务提供者的名字

      判断有没有服务提供者#

      public boolean hasNext() { if (acc == null) { return hasNextService(); } else { PrivilegedAction action = new PrivilegedAction() { public Boolean run() { return hasNextService(); } }; return AccessController.doPrivileged(action, acc); } }

      判断有没有服务#

      private boolean hasNextService() { if (nextName != null) { return true; } if (configs == null) { try { String fullName = PREFIX + service.getName(); // 加载所有服务提供者配置文件 if (loader == null) configs = ClassLoader.getSystemResources(fullName); else configs = loader.getResources(fullName); } catch (IOException x) { fail(service, "Error locating configuration files", x); } } while ((pending == null) || !pending.hasNext()) { if (!configs.hasMoreElements()) { return false; } # 从配置信息中解析服务提供者类,找不到返回空 pending = parse(service, configs.nextElement()); } //设置下一个服务提供者的类名,next方法使用名字加载和初始化对应的实现类 nextName = pending.next(); return true; }

      获取下一个服务提供者#

      public S next() { if (acc == null) { return nextService(); } else { PrivilegedAction action = new PrivilegedAction() { public S run() { return nextService(); } }; return AccessController.doPrivileged(action, acc); } }

      获取下一个服务提供者类#

      private S nextService() { if (!hasNextService()) throw new NoSuchElementException(); String cn = nextName; nextName = null; Class<?> c = null; try { # 加载类信息 c = Class.forName(cn, false, loader); } catch (ClassNotFoundException x) { fail(service, "Provider " + cn + " not found"); } if (!service.isAssignableFrom(c)) { fail(service, "Provider " + cn + " not a subtype"); } try { # 初始化类 S p = service.cast(c.newInstance()); providers.put(cn, p); return p; } catch (Throwable x) { fail(service, "Provider " + cn + " could not be instantiated", x); } throw new Error(); // This cannot happen }