apollo如何获取server地址和appId

723 阅读1分钟

本文会讲解apollo客户端如何读取基础配置的,顺带手讲解SPI机制。

我们定位到Foundation类,Foundation类有一个静态代码块,

static {
  getManager();
}

private static ProviderManager getManager() {
  try {
    if (s_manager == null) {
      // Double locking to make sure only one thread initializes ProviderManager.
      synchronized (lock) {
        if (s_manager == null) {
          s_manager = ServiceBootstrap.loadFirst(ProviderManager.class);
        }
      }
    }

    return s_manager;
  } catch (Throwable ex) {
    s_manager = new NullProviderManager();
    logger.error("Initialize ProviderManager failed.", ex);
    return s_manager;
  }
}

ProviderManager是一个接口,这里的loadFirst方法是运用了SPI机制获取到它的实现类,并进行实例化。

如何才能通过SPI加载实现类

1.需要在META-INF.service路径下添加文本文件,将接口的全名作为文件名,文件内容为实现类的全名:

apollo如何获取server地址和appId

文件路径

apollo如何获取server地址和appId

文本文件

2.代码获取实现类

public static <S> S loadFirst(Class<S> clazz) {
    //获取文本文件中所有的实现类对象
    Iterator<S> iterator = loadAll(clazz);
    if (!iterator.hasNext()) {
      throw new IllegalStateException(String.format(
          "No implementation defined in /META-INF/services/%s, please check whether the file exists and has the right implementation class!",
          clazz.getName()));
    }
    //只取第一个实现类
    return iterator.next();
  }

public static <S> Iterator<S> loadAll(Class<S> clazz) {
  //获取文本文件中所有的实现类对象
  ServiceLoader<S> loader = ServiceLoader.load(clazz);

  return loader.iterator();
}

loadFirst方法获取到DefaultProviderManager对象。

读取META-INF/app.properties

我们来看下DefaultProviderManager的构造方法

public DefaultProviderManager() {
  // Load per-application configuration, like app id, from classpath://META-INF/app.properties
  Provider applicationProvider = new DefaultApplicationProvider();
  applicationProvider.initialize();
  register(applicationProvider);

  // Load network parameters
  Provider networkProvider = new DefaultNetworkProvider();
  networkProvider.initialize();
  register(networkProvider);

  // Load environment (fat, fws, uat, prod ...) and dc, from /opt/settings/server.properties, JVM property and/or OS
  // environment variables.
  Provider serverProvider = new DefaultServerProvider();
  serverProvider.initialize();
  register(serverProvider);
}

DefaultApplicationProvider类的initialize方法会读取META-INF/app.properties文件的配置项,并放到Properties中,Properties类继承自Hashtable。我们需要获取地址的时候,从Properties对象中获取key=apollo.meta的值即可。

这里我们需要注意一点,就是apollo的服务器地址和appId一定要放到/META-INF/app.properties里面,路径和文件名是固定的,因为这在apollo代码里写死的。

apollo如何获取server地址和appId