apollo客户端-首次获取server数据?

......

public class ApolloApplicationContextInitializer implements 
public class ApolloApplicationContextInitializer implements
// 这个接口允许在ConfigurableApplicationContext(如AnnotationConfigApplicationContext或XmlWebApplicationContext等)刷新(refresh)之前对其进行初始化操作。
// 可以在应用上下文启动但还未加载 bean 定义之前,对上下文进行自定义的设置和初始化操作
ApplicationContextInitializer<ConfigurableApplicationContext>, 
// 这个接口允许在 Spring 应用的Environment准备好之后对其进行进一步的处理和定制。
// 可以在 Spring 应用上下文加载环境变量、系统属性和配置文件等之后,对Environment对象进行额外的配置和调整。
EnvironmentPostProcessor, 
Ordered 
{
    // 默认顺序
    public static final int DEFAULT_ORDER = 0;
    // 日志
    private static final Logger logger = LoggerFactory.getLogger(ApolloApplicationContextInitializer.class);
    // namespace分割
    private static final Splitter NAMESPACE_SPLITTER = Splitter.on(",").omitEmptyStrings().trimResults();
    // apollo系统特性
    private static final String[] APOLLO_SYSTEM_PROPERTIES = new String[]{
        "app.id",
        "apollo.cluster",
        "apollo.cacheDir", 
        "apollo.accesskey.secret", 
        "apollo.meta", 
        "apollo.property.order.enable"
    };
    // 拿到一个线程安全的配置工厂对象
    private final ConfigPropertySourceFactory configPropertySourceFactory = (ConfigPropertySourceFactory)SpringInjector.getInstance(ConfigPropertySourceFactory.class);
    private int order = 0;

    public ApolloApplicationContextInitializer() {
    }

    // ApolloApplicationContextInitializer在initialize方法中对应用上下文进行初始化操作
    @Override
    public void initialize( /**当前应用上下文**/ConfigurableApplicationContext context) {
        ConfigurableEnvironment environment = context.getEnvironment();
        if (!(Boolean)environment.getProperty("apollo.bootstrap.enabled", Boolean.class, false)) {
            logger.debug("Apollo bootstrap config is not enabled for context {}, see property: ${
  {}}", context, "apollo.bootstrap.enabled");
        } else {
            logger.debug("Apollo bootstrap config is enabled for context {}", context);
            this.initialize(environment);
        }
    }

    // 当前累自定义的方法:initialize
    protected void initialize(/**当前应用的配置环境**/ConfigurableEnvironment environment) {
        // 检测是否已经有了组合属性对象(经过处理话后,会在环境对象中创建一个,没有则说明尚未完成初始化)
        if (!environment.getPropertySources().contains("ApolloBootstrapPropertySources")) {
            // 获取配置的apollo的namespace,默认为:application
            String namespaces = environment.getProperty("apollo.bootstrap.namespaces", "application");
            logger.debug("Apollo bootstrap namespaces: {}", namespaces);
            // 按照英文:“,”进行分割,拿到命名空间集合
            List<String> namespaceList = NAMESPACE_SPLITTER.splitToList(namespaces);
            
            // 创建一个组合属性对象
            CompositePropertySource composite = new CompositePropertySource("ApolloBootstrapPropertySources");

            // 拿到迭代器:准备迭代处理
            Iterator i$ = namespaceList.iterator();
            while(i$.hasNext()) {
                // 命名空间名称
                String namespace = (String)i$.next();
                // 拿到具体的配置(重点逻辑:这里面有从apollo-server获取陪配置数据的逻辑)
                Config config = ConfigService.getConfig(namespace);
                // 往组合属性对象中丢数据
                composite.addPropertySource(this.configPropertySourceFactory.getConfigPropertySource(namespace, config));
            }
            // 最终数据打包丢到环境对象中
            environment.getPropertySources().addFirst(composite);
        }
    }

    void initializeSystemProperty(/**当前应用的配置环境**/ConfigurableEnvironment environment) {
        String[] arr$ = APOLLO_SYSTEM_PROPERTIES;
        int len$ = arr$.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            String propertyName = arr$[i$];
            this.fillSystemPropertyFromEnvironment(environment, propertyName);
        }

    }

    private void fillSystemPropertyFromEnvironment(/**当前应用的配置环境**/ConfigurableEnvironment environment, 
                                                   String propertyName) {
        if (System.getProperty(propertyName) == null) {
            String propertyValue = environment.getProperty(propertyName);
            if (!Strings.isNullOrEmpty(propertyValue)) {
                System.setProperty(propertyName, propertyValue);
            }
        }
    }

    // 在postProcessEnvironment方法中对环境进行处理
    // 执行时间节点:高于initialize( /**当前应用上下文**/ConfigurableApplicationContext context)
    @Override
    public void postProcessEnvironment(/**当前应用的配置环境**/ConfigurableEnvironment configurableEnvironment, 
                                       SpringApplication springApplication) {
        // 初始化系统参数
        this.initializeSystemProperty(configurableEnvironment);
        // # 表示启用急切加载。
        // 急切加载意味着在应用启动时,Apollo 客户端会尽快加载配置,而不是在首次访问配置时才加载。这可以确保应用在启动过程中尽早获取到所需的配置信息,减少潜在的延迟和不确定性。
        Boolean eagerLoadEnabled = (Boolean)configurableEnvironment.getProperty("apollo.bootstrap.eagerLoad.enabled", Boolean.class, false);
        if (eagerLoadEnabled) {
            //  # 启用 Apollo 的引导程序,这是使 Apollo 客户端在应用启动时生效的关键设置。
            Boolean bootstrapEnabled = (Boolean)configurableEnvironment.getProperty("apollo.bootstrap.enabled", Boolean.class, false);
            if (bootstrapEnabled) {
                // 只有配置了对应的参数,才会执行初始化逻辑
                this.initialize(configurableEnvironment);
            }

        }
    }

    // 通过getOrder方法返回一个执行顺序值
    @Override
    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }
}

触发顺序:

EnvironmentPostProcessor

  1. postProcessEnvironment(**) [ApolloApplicationContextInitializer.java]
  2. this.initialize(configurableEnvironment) [ApolloApplicationContextInitializer.java]
  3. Config config = ConfigService.getConfig(namespace) [ApolloApplicationContextInitializer.java]
  4. Config getConfig(String namespace) [ConfigService.java]
  5. getConfig(String namespace) [DefaultConfigManager.java]
    • factory.create(namespace)
  1. Config create(String namespace) [DefaultConfigFactory.java]
    • new DefaultConfig(namespace, this.createLocalConfigRepository(namespace)) :
      • this.createLocalConfigRepository(namespace) :
        • new LocalFileConfigRepository(*,this.createRemoteConfigRepository(namespace));
          • createRemoteConfigRepository(String namespace)
            • 创建RemoteConfigRepository对象,启动各种触发机制
              1. RemoteConfigRepository(String namespace) [RemoteConfigRepository.java]
                • this.trySync();
                • this.scheduleLongPollingRefresh();
    • 最后DefaultConfig 类型包装一下
  1. 数据刷新到环境中
    • composite.addPropertySource(this.configPropertySourceFactory.getConfigPropertySource(namespace, config));

environment.getPropertySources().addFirst(composite);

public RemoteConfigRepository(String namespace) {
        // 命名空间
        this.m_namespace = namespace;
        //
        this.m_configCache = new AtomicReference();
        // 
        this.m_configUtil = (ConfigUtil)ApolloInjector.getInstance(ConfigUtil.class);
        this.m_httpUtil = (HttpUtil)ApolloInjector.getInstance(HttpUtil.class);
        this.m_serviceLocator = (ConfigServiceLocator)ApolloInjector.getInstance(ConfigServiceLocator.class);
        // 获取远程配置数据:LongPoll实时通讯交互服务,apollo动态刷新就靠它了~(定义一个服务,后面有逻辑触发)
        this.remoteConfigLongPollService = (RemoteConfigLongPollService)ApolloInjector.getInstance(RemoteConfigLongPollService.class);
        this.m_longPollServiceDto = new AtomicReference();
        this.m_remoteMessages = new AtomicReference();
        // 限流
        this.m_loadConfigRateLimiter = RateLimiter.create((double)this.m_configUtil.getLoadConfigQPS());
        this.m_configNeedForceRefresh = new AtomicBoolean(true);
        this.m_loadConfigFailSchedulePolicy = new ExponentialSchedulePolicy(this.m_configUtil.getOnErrorRetryInterval(), this.m_configUtil.getOnErrorRetryInterval() * 8L);
        this.gson = new Gson();
        // 触发一次同步操作:拉取一次数据(apollo客户端首次拉取配置数据)
        this.trySync();
        // 刷新任务:主动拉取数据
        this.schedulePeriodicRefresh();
        // 实时刷新任务:启动longpolling机制
        this.scheduleLongPollingRefresh();
    }
    private void schedulePeriodicRefresh() {
        logger.debug("Schedule periodic refresh with interval: {} {}", this.m_configUtil.getRefreshInterval(), this.m_configUtil.getRefreshIntervalTimeUnit());
        m_executorService.scheduleAtFixedRate(
            // 定时任务逻辑
            new Runnable() {
                    public void run() {
                        Tracer.logEvent("Apollo.ConfigService", String.format("periodicRefresh: %s", RemoteConfigRepository.this.m_namespace));
                        RemoteConfigRepository.logger.debu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成熟的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值