【Apollo】【一】Apollo 配置首次加载过程
1 前言
今天我们来看看 Apollo的东西,比如我们的项目引入了 Apollo,那么我们的服务启动的时候,会首先从Apollo读取配置那么它是怎么做的呢,这节我们就来瞅瞅。
Apollo版本:1.7
大家可以自己去下载安装一个哈,方便自己调试,边看边调试可以有个更好的理解哈。
2 源码分析
2.1 @EnableApolloConfig 入口
首先 apollo引入后,大概会引进两块的内容,一块是client包,一块是它的核心包。并且每个包下边有SPI的类或者 spring.factories,这两类东西应该很敏感哈,SPI他会加载你的类,spring.factories是spring会加载的类。我看了他们引进的类,没什么特别特殊的地方,真正在我们的服务启动的时候去加载配置的还是 @EnableApolloConfig 注解为入口的。
我们看看 @EnableApolloConfig 引进的类:ApolloConfigRegistrar,从名字上看就可以理解他是 Apollo的配置注册类。我们继续进入看看:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(ApolloConfigRegistrar.class) public @interface EnableApolloConfig { /** * Apollo namespaces to inject configuration into Spring Property Sources. */ String[] value() default {ConfigConsts.NAMESPACE_APPLICATION}; /** * The order of the apollo config, default is {@link Ordered#LOWEST_PRECEDENCE}, which is Integer.MAX_VALUE. * If there are properties with the same name in different apollo configs, the apollo config with smaller order wins. * @return */ int order() default Ordered.LOWEST_PRECEDENCE; }
这里我简单串一下 ApolloConfigRegistrar 的执行来源过程哈,来源于 spring 中的BeanDefinitionRegistryPostProcessors,继而通过 ConfigurationClassPostProcessor 后置处理,筛选出 ImportBeanDefinitionRegistrar 配置类,进行注册。如下图:
2.2 ApolloConfigRegistrar
那我们来看看 ApolloConfigRegistrar,它是交给 ApolloConfigRegistrarHelper 来注册一些 bean的,这种写法大家平时写代码也可以参考参考,相当于把逻辑交给一个对象专门来处理,下沉一层,方便扩展,各司其职,我们看看:
public class ApolloConfigRegistrar implements ImportBeanDefinitionRegistrar { private ApolloConfigRegistrarHelper helper = ServiceBootstrap.loadPrimary(ApolloConfigRegistrarHelper.class); @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { helper.registerBeanDefinitions(importingClassMetadata, registry); } }
public class DefaultApolloConfigRegistrarHelper implements ApolloConfigRegistrarHelper { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AnnotationAttributes attributes = AnnotationAttributes .fromMap(importingClassMetadata.getAnnotationAttributes(EnableApolloConfig.class.getName())); String[] namespaces = attributes.getStringArray("value"); int order = attributes.getNumber("order"); PropertySourcesProcessor.addNamespaces(Lists.newArrayList(namespaces), order); Map<String, Object> propertySourcesPlaceholderPropertyValues = new HashMap<>(); // to make sure the default PropertySourcesPlaceholderConfigurer's priority is higher than PropertyPlaceholderConfigurer propertySourcesPlaceholderPropertyValues.put("order", 0); BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(), PropertySourcesPlaceholderConfigurer.class, propertySourcesPlaceholderPropertyValues); BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesProcessor.class.getName(), PropertySourcesProcessor.class); BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(), ApolloAnnotationProcessor.class); BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(), SpringValueProcessor.class); BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueDefinitionProcessor.class.getName(), SpringValueDefinitionProcessor.class); BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloJsonValueProcessor.class.getName(), ApolloJsonValueProcessor.class); } @Override public int getOrder() { return Ordered.LOWEST_PRECEDENCE; } }
可以看到注册器,引进了一堆后置处理器,那么我们的配置在 Apollo 的配置是由谁去加载的呢?其实就是 PropertySourcesProcessor 属性源。
2.3 PropertySourcesProcessor
我们看看 PropertySourcesProcessor 获取配置的一个过程:
获取完配置信息后,把它封装进了 CompositePropertySource 属性源里,并放进了环境变量里,这样我们的Bean在初始化的时候,是不是就赋值啦。
3 小结
好啦,本节我们主要是看一下 Apollo 获取配置的入口过程哈,有理解不对的地方欢迎指正哈。