配置中心Apollo

Apollo(4) Client包

2022-12-09  本文已影响0人  Oliver_Li
一、常用使用方式和功能:
  1. apollo引入方式:
  1. 常见用法:
二、Spring周期和Apollo相关扩展点:
三、代码部分:
  1. 官方对Client流程的整体描述,接Config Service长轮询部分


  2. Config、ConfigRepository:Apollo对配置和仓库等概念的抽象
  1. 启动方式apollo.bootstrap.enabled和@EnableApolloConfig:
  1. @EnableApolloConfig注解:
  1. 准备阶段ApolloApplicationContextInitializer:
  1. DefaultApolloConfigRegistrarHelper加入Apollo自定义Bean:③
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    // 获取所有@EnableApolloConfig注解和参数
    AnnotationAttributes attributes = AnnotationAttributes
        .fromMap(importingClassMetadata.getAnnotationAttributes(EnableApolloConfig.class.getName()));
    final String[] namespaces = attributes.getStringArray("value");
    final int order = attributes.getNumber("order");
    // 解析namespaces里的占位符并添加到PropertySourcesProcessor
    final String[] resolvedNamespaces = this.resolveNamespaces(namespaces);
    PropertySourcesProcessor.addNamespaces(Lists.newArrayList(resolvedNamespaces), order);

    // 配置PropertySourcesPlaceholderConfigurer优先级
    Map<String, Object> propertySourcesPlaceholderPropertyValues = new HashMap<>();
    propertySourcesPlaceholderPropertyValues.put("order", 0);

    // 处理配置里的占位符(BeanFactoryPostProcessor)
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class, propertySourcesPlaceholderPropertyValues);
    // 更新@Value实现不用@RefreshScope刷新
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, AutoUpdateConfigChangeListener.class);
    // 处理@EnableApolloConfig的namespace,(配置文件启动方式里没有这个注解,所以去掉了这部分)
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesProcessor.class);
    // 处理@ApolloConfig、@ApolloJsonValue、@ApolloConfigChangeListener并注入相关信息
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class);
    // 收集@Value和xml的配置信息放入SpringValueRegistry
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class);
    // 把xml中的配置信息提取出来key 占位符等等并存储,在SpringValueProcessor作出处理
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueDefinitionProcessor.class);
  }
  1. SpringValueDefinitionProcessor:④
  1. PropertySourcesProcessor:⑤
  1. PropertySourcesPlaceholderConfigurer:⑥
  1. SpringValueProcessor:
  1. ApolloAnnotationProcessor:⑧
  1. AutoUpdateConfigChangeListener:配置更新时@Value实现自动更新的Bean!⑩
public class PlaceholderHelper {
    ...
    /**
   * 把占位符解析成具体值
   */
    public Object resolvePropertyValue(ConfigurableBeanFactory beanFactory, String beanName, String placeholder) {
    // 获取解析的值
    String strVal = beanFactory.resolveEmbeddedValue(placeholder);

    BeanDefinition bd = (beanFactory.containsBean(beanName) ? beanFactory
        .getMergedBeanDefinition(beanName) : null);

    // resolve expressions like "#{systemProperties.myProp}"
    return evaluateBeanDefinitionString(beanFactory, strVal, bd);
  }
    ...
}
public class SpringValue {
  ......
  // field.set()给字段设置新值
  private void injectField(Object newVal) throws IllegalAccessException {
    Object bean = beanRef.get();
    if (bean == null) {
      return;
    }
    boolean accessible = field.isAccessible();
    field.setAccessible(true);
    field.set(bean, newVal);
    field.setAccessible(accessible);
  }

  // 用方法设置新值
  private void injectMethod(Object newVal)
      throws InvocationTargetException, IllegalAccessException {
    Object bean = beanRef.get();
    if (bean == null) {
      return;
    }
    methodParameter.getMethod().invoke(bean, newVal);
  }
    ......
}
  1. 总结:Clinet部分主要了解一是对配置,包括远程、本地的抽象。二是Apollo在Spring的关键扩展点做的处理;最后就是长轮训Client怎么和meta service、config service通信

源码里相关的知识点:

  1. Environment和PropertySource:https://www.codenong.com/jsf6f51ff3e0f2/

  2. 总结:Environment包括Java环境变量、系统环境变量等。PropertySource代表数据源,以kv形式使用配置,Environment里加入了各种源的PropertySource直接使用,也可以自定义配置数据源到Environment。apollo里所有namespace都放在了Environment下的PropertySource,PropertySource下的source获取具体配置kv

  3. @Value:https://blog.csdn.net/weixin_46228112/article/details/124623568

  4. 总结:@Value数据来源于PropertySource或者间接说是Environment,但改变PropertySource并不会改变运行时的值,有两种方式一是@RefreshScope刷新bean,二是apollo里用反射直接设置

  5. @ConfigurationProperties:https://blog.csdn.net/qq_31854907/article/details/121470769

  6. 总结:bean后置处理器,和@Value类似都是从PropertySource获取,然后绑定到bean里

  7. @RefreshScope:https://blog.csdn.net/luqiang81191293/article/details/106678065

  8. 总结:使用@Scope做了代理,正常使用时会使用RefreshScope父类里缓存的Bean,可执行清理,清理后会重新创建Bean达到刷新的目的,apollo里@ConfigurationProperties需要用户添加@RefreshScope+调用refresh()才能实现刷新

  9. ImportBeanDefinitionRegistrar:使用ImportBeanDefinitionRegistrar动态创建自定义Bean到Spring中

  10. 总结:在spring周期中用来处理自定义BeanDefinition,调用在Bean初始化之前,Apollo中在这个扩展点中加入的配置注册、变更监听等相关逻辑

  11. multimap:Java使用multimap数据结构_srping123的博客-CSDN博客_java multimap

上一篇下一篇

猜你喜欢

热点阅读