一、spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.ctrip.framework.apollo.spring.boot.ApolloAutoConfiguration
二、ApolloAutoConfiguration配置
1、ApolloAutoConfiguration
- 当apollo.bootstrap.enabled注入
- 注入了ConfigPropertySourcesProcessor
@Configuration
@ConditionalOnProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED)
@ConditionalOnMissingBean(PropertySourcesProcessor.class)
public class ApolloAutoConfiguration {
@Bean
public ConfigPropertySourcesProcessor configPropertySourcesProcessor() {
return new ConfigPropertySourcesProcessor();
}
}
2、ConfigPropertySourcesProcessor
- 这里用到了JDK SPI来加载ConfigPropertySourcesProcessorHelper,方便后续扩展
- Spring触发阶段:AbstractApplicationContext#invokeBeanFactoryPostProcessors,调用所有BeanDefinitionRegistryPostProcessor
public class ConfigPropertySourcesProcessor extends PropertySourcesProcessor
implements BeanDefinitionRegistryPostProcessor {
// 使用JDK SPI机制加载第一个ConfigPropertySourcesProcessorHelper, 这里是DefaultConfigPropertySourcesProcessorHelper
private ConfigPropertySourcesProcessorHelper helper = ServiceBootstrap.loadPrimary(ConfigPropertySourcesProcessorHelper.class);
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
helper.postProcessBeanDefinitionRegistry(registry);
}
}
3、DefaultConfigPropertySourcesProcessorHelper负责注入几个bean
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Map<String, Object> propertySourcesPlaceholderPropertyValues = new HashMap<>();
propertySourcesPlaceholderPropertyValues.put("order", 0);
// 1. 注册Spring的PropertySourcesPlaceholderConfigurer,负责操作Spring的PropertySources,是spring配置的来源
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(),
PropertySourcesPlaceholderConfigurer.class, propertySourcesPlaceholderPropertyValues);
// 2. ApolloConfig属性级别注解和ApolloConfigChangeListener方法级别注解的支持
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(),
ApolloAnnotationProcessor.class);
// 3. 解析@Value注解,并抽象为SpringValue,注册到单例的SpringValueRegistry中保存
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(),
SpringValueProcessor.class);
// 4. 方法和属性级别的ApolloJsonValue注解的支持
BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloJsonValueProcessor.class.getName(),
ApolloJsonValueProcessor.class);
// 5. xml的beanDefination处理,抽象每个Field的信息为SpringValueDefinition,保存到SpringValueDefinitionProcessor的一个map中
// Map<BeanDefinitionRegistry, Multimap<String, SpringValueDefinition>> beanName2SpringValueDefinitions
processSpringValueDefinition(registry);
}
4、ApolloProcessor和它的子类
ApolloProcessor是一个抽象类,实现了BeanPostProcessor接口,负责在Bean初始化之前,注入Apollo的配置,并把Spring的@Value抽象成对象,注册到Apollo自己的一个单例SpringValueRegistry中,方便后续的配置更新。processField和processMethod是两个抽象方法,由子类实现属性和方法的处理方式。
public abstract class ApolloProcessor implements BeanPostProcessor, PriorityOrdered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
Class clazz = bean.getClass();
for (Field field : findAllField(clazz)) {
processField(bean, beanName, field);
}
for (Method method : findAllMethod(clazz)) {
processMethod(bean, beanName, method);
}
return bean;
}
}
4-1、ApolloAnnotationProcessor
ApolloAnnotationProcessor主要是处理两个注解
- 属性级别注解ApploConfig,负责注入阿波罗的Config对象,可以获取某个namespace下的Config
- 方法级别注解ApolloConfigChangeListener,负责向Config对象中添加监听器,当配置发生变化时可以收到通知
public class ApolloAnnotationProcessor extends ApolloProcessor {
/**
* 处理@ApploConfig(namespace)注解的属性,注入Apollo的Config
*/
@Override
protected void processField(Object bean, String beanName, Field field) {
ApolloConfig annotation = AnnotationUtils.getAnnotation(field, ApolloConfig.class);
// 校验字段必须是Config类型
Preconditions.checkArgument(Config.class.isAssignableFrom(field.getType()),
"Invalid type: %s for field: %s, should be Config", field.getType(), field);
String namespace = annotation.value();
// 根据namespace获取阿波罗Config
Config config = ConfigService.getConfig(namespace);
// 反射设置这个field
ReflectionUtils.makeAccessible(field);
ReflectionUtils.setField(field, bean, config);
}
/**
* 1、从method上找到ApolloConfigChangeListener注解
* 2、创建ConfigChangeListener---目的是当配置发生变化时,反射调用ApolloConfigChangeListener注解的方法
* 3、注册ConfigChangeListener到每个Namespace的Config上
*/
@Override
protected void processMethod(final Object bean, String beanName, final Method method) {
ApolloConfigChangeListener annotation = AnnotationUtils
.findAnnotation(method, ApolloConfigChangeListener.class);
Class<?>[] parameterTypes = method.getParameterTypes();
ReflectionUtils.makeAccessible(method);
String[] namespaces = annotation.value();
String[] annotatedInterestedKeys = annotation.interestedKeys();
String[] annotatedInterestedKeyPrefixes = annotation.interestedKeyPrefixes();
// 监听Apollo配置发生变化的Listener,当有配置发生变化会调用ConfigChangeListener的onChange方法
ConfigChangeListener configChangeListener = new ConfigChangeListener() {
@Override
public void onChange(ConfigChangeEvent changeEvent) {
ReflectionUtils.invokeMethod(method, bean, changeEvent);
}
};
Set<String> interestedKeys = annotatedInterestedKeys.length > 0 ? Sets.newHashSet(annotatedInterestedKeys) : null;
Set<String> interestedKeyPrefixes = annotatedInterestedKeyPrefixes.length > 0 ? Sets.newHashSet(annotatedInterestedKeyPrefixes) : null;
// 循环每个namespace,向他们的Config对象注册ConfigChangeListener
for (String namespace : namespaces) {
Config config = ConfigService.getConfig(namespace);
if (interestedKeys == null && interestedKeyPrefixes == null) {
config.addChangeListener(configChangeListener);
} else {
config.addChangeListener(configChangeListener, interestedKeys, interestedKeyPrefixes);
}
}
}
}
4-2、SpringValueProcessor
SpringValueProcessor主要是把类、方法、Spring的@Value注解抽象成SpringValue对象,注册到单例的SpringValueRegistry中,后续配置发生变化时,会从Registry中取出相应的SpringValue,然后通过反射实现@Value注解修饰方法和属性的更新
public class SpringValueProcessor extends ApolloProcessor implements BeanFactoryPostProcessor, BeanFactoryAware {
// apollo客户端配置
private final ConfigUtil configUtil;
// 占位符操作辅助类
private final PlaceholderHelper placeholderHelper;
// SpringValue注册中心
private final SpringValueRegistry springValueRegistry;
// SpringBean工厂
private BeanFactory beanFactory;
// Xml配置的bean key是beanName value是Spring@Value的抽象
private Multimap<String, SpringValueDefinition> beanName2SpringValueDefinitions;
// BeanFactory后置处理,从SpringValueDefinitionProcessor获取到BeanName和所有SpringValueDefinition的映射关系,SpringValueDefinition是对xml配置的value属性的一层抽象
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
beanName2SpringValueDefinitions = SpringValueDefinitionProcessor
.getBeanName2SpringValueDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 重写了ApolloProcessor的postProcessBeforeInitialization
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
// ApolloProcessor#postProcessBeforeInitialization
// 1. processField field级别的@Value,放到SpringValueRegistry中
// 2. processMethod 方法级别的@Value,放到SpringValueRegistry中
super.postProcessBeforeInitialization(bean, beanName);
// 3. 处理xml注册的bean的配置
processBeanPropertyValues(bean, beanName);
return bean;
}
@Override
protected void processField(Object bean, String beanName, Field field) {
// register @Value on field
Value value = field.getAnnotation(Value.class);
// 解析@Value的value属性,因为@Value可能有多个占位符等原因,获取到所有需要配置的key
Set<String> keys = placeholderHelper.extractPlaceholderKeys(value.value());
// 循环注册到springValueRegistry
for (String key : keys) {
SpringValue springValue = new SpringValue(key, value.value(), bean, beanName, field, false);
springValueRegistry.register(beanFactory, key, springValue);
}
}
@Override
protected void processMethod(Object bean, String beanName, Method method) {
//register @Value on method
Value value = method.getAnnotation(Value.class);
// 跳过了@Bean注解的方法
if (method.getAnnotation(Bean.class) != null) {
return;
}
// 解析@Value的value属性,因为@Value可能有多个占位符等原因,获取到所有需要配置的key
Set<String> keys = placeholderHelper.extractPlaceholderKeys(value.value());
// 循环注册到springValueRegistry
for (String key : keys) {
SpringValue springValue = new SpringValue(key, value.value(), bean, beanName, method, false);
springValueRegistry.register(beanFactory, key, springValue);
}
}
// 处理xml注册的bean的配置
private void processBeanPropertyValues(Object bean, String beanName) {
Collection<SpringValueDefinition> propertySpringValues = beanName2SpringValueDefinitions
.get(beanName);
for (SpringValueDefinition definition : propertySpringValues) {
PropertyDescriptor pd = BeanUtils
.getPropertyDescriptor(bean.getClass(), definition.getPropertyName());
Method method = pd.getWriteMethod();
SpringValue springValue = new SpringValue(definition.getKey(), definition.getPlaceholder(),
bean, beanName, method, false);
springValueRegistry.register(beanFactory, definition.getKey(), springValue);
}
// clear
beanName2SpringValueDefinitions.removeAll(beanName);
}
}
4-3、ApolloJsonValueProcessor
- 负责处理方法和属性级别的@ApolloJsonValue,把配置通过反射注入bean
- 抽象为SpringValue注册到SpringValueRegistry,处理以后的配置更新
public class ApolloJsonValueProcessor extends ApolloProcessor implements BeanFactoryAware {
@Override
protected void processField(Object bean, String beanName, Field field) {
// 1. 解析ApolloJsonValue
ApolloJsonValue apolloJsonValue = AnnotationUtils.getAnnotation(field, ApolloJsonValue.class);
String placeholder = apolloJsonValue.value();
Object propertyValue = placeholderHelper
.resolvePropertyValue(beanFactory, beanName, placeholder);
// 2. 反射执行setter
boolean accessible = field.isAccessible();
field.setAccessible(true);
ReflectionUtils
.setField(field, bean, parseJsonValue((String)propertyValue, field.getGenericType()));
field.setAccessible(accessible);
// 3. 注册到SpringValueRegistry
if (configUtil.isAutoUpdateInjectedSpringPropertiesEnabled()) {
Set<String> keys = placeholderHelper.extractPlaceholderKeys(placeholder);
for (String key : keys) {
SpringValue springValue = new SpringValue(key, placeholder, bean, beanName, field, true);
springValueRegistry.register(beanFactory, key, springValue);
}
}
}
@Override
protected void processMethod(Object bean, String beanName, Method method) {
// 1. 解析ApolloJsonValue
ApolloJsonValue apolloJsonValue = AnnotationUtils.getAnnotation(method, ApolloJsonValue.class);
String placeHolder = apolloJsonValue.value();
Object propertyValue = placeholderHelper
.resolvePropertyValue(beanFactory, beanName, placeHolder);
// 2. 反射执行方法
Type[] types = method.getGenericParameterTypes();
boolean accessible = method.isAccessible();
method.setAccessible(true);
ReflectionUtils.invokeMethod(method, bean, parseJsonValue((String)propertyValue, types[0]));
method.setAccessible(accessible);
// 3. 注册到SpringValueRegistry
if (configUtil.isAutoUpdateInjectedSpringPropertiesEnabled()) {
Set<String> keys = placeholderHelper.extractPlaceholderKeys(placeHolder);
for (String key : keys) {
SpringValue springValue = new SpringValue(key, apolloJsonValue.value(), bean, beanName,
method, true);
springValueRegistry.register(beanFactory, key, springValue);
}
}
}
private Object parseJsonValue(String json, Type targetType) {
return gson.fromJson(json, targetType);
}
}