nacos2.x客户端与Spring Boot源码解析(@NacosConfigurationProperties怎么实现配置文件热更新的)

两种实现方式:

  1. NacosConfigEnvironmentProcessor:负责在应用程序启动前加载远程配置
  2. NacosConfigAutoConfiguration:负责完成Nacos配置管理相关功能的配置加载与初始化

1、@NacosConfigurationProperties
1.1@NacosConfigurationProperties怎么被识别的
Nacos提供了NacosConfigurationPropertiesBindingPostProcessor

  • 扫描类上的是否有@NacosConfigurationProperties注解
public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {

		NacosConfigurationProperties nacosConfigurationProperties = findAnnotation(
				bean.getClass(), NacosConfigurationProperties.class);

		if (nacosConfigurationProperties != null) {
			bind(bean, beanName, nacosConfigurationProperties);
		}

		return bean;
	}
  • 获取@NacosConfigurationProperties构造器实例
private void bind(Object bean, String beanName,
			NacosConfigurationProperties nacosConfigurationProperties) {

		NacosConfigurationPropertiesBinder binder;
		try {
			binder = applicationContext.getBean(
					NacosConfigurationPropertiesBinder.BEAN_NAME,
					NacosConfigurationPropertiesBinder.class);
			if (binder == null) {
				binder = new NacosConfigurationPropertiesBinder(applicationContext);
			}

		}
		catch (Exception e) {
			binder = new NacosConfigurationPropertiesBinder(applicationContext);
		}

		binder.bind(bean, beanName, nacosConfigurationProperties);

	}
  • 获取NacosConfigService服务
  • 创建监听,并将监听器添加到NacosConfigService服务中
protected void bind(final Object bean, final String beanName,
			final NacosConfigurationProperties properties) {

		Assert.notNull(bean, "Bean must not be null!");

		Assert.notNull(properties, "NacosConfigurationProperties must not be null!");

		// support read data-id and group-id from spring environment
		final String dataId = NacosUtils.readFromEnvironment(properties.dataId(),
				environment);
		final String groupId = NacosUtils.readFromEnvironment(properties.groupId(),
				environment);
		final String type;
		
		ConfigType typeEunm = properties.yaml() ? ConfigType.YAML : properties.type();
		if (ConfigType.UNSET.equals(typeEunm)) {
			type = NacosUtils.readFileExtension(dataId);
		}
		else {
			type = typeEunm.getType();
		}

		final ConfigService configService = configServiceBeanBuilder
				.build(properties.properties());

		// Add a Listener if auto-refreshed
		if (properties.autoRefreshed()) {
			
			String content = getContent(configService, dataId, groupId);
			
			if (hasText(content)) {
				doBind(bean, beanName, dataId, groupId, type, properties, content,
						configService);
			}

			Listener listener = new AbstractListener() {
				@Override
				public void receiveConfigInfo(String config) {
					doBind(bean, beanName, dataId, groupId, type, properties, config,
							configService);
				}
			};
			try {//
				if (configService instanceof EventPublishingConfigService) {
					((EventPublishingConfigService) configService).addListener(dataId,
							groupId, type, listener);
				}
				else {
					configService.addListener(dataId, groupId, listener);
				}
			}
			catch (NacosException e) {
				if (logger.isErrorEnabled()) {
					logger.error(e.getMessage(), e);
				}
			}
		}
	}

2、更新数据
当在配置更新时,回调listener监听器,执行NacosBootConfigurationPropertiesBinder.doBind方法

  • 注解配置的配置文件临时加入到默认的StandardEnvironment中
  • 通过SpringBoot Binder将StandardEnvironment配置项绑定(注入)到bean
  • 解析完成后再移除注入
protected void doBind(Object bean, String beanName, String dataId, String groupId,
			String configType, NacosConfigurationProperties properties, String content,
			ConfigService configService) {
		synchronized (this) {
			String name = "nacos-bootstrap-" + beanName;
			NacosPropertySource propertySource = new NacosPropertySource(name, dataId, groupId, content, configType);
			environment.getPropertySources().addLast(propertySource);
			Binder binder = Binder.get(environment);
			ResolvableType type = getBeanType(bean, beanName);
			Bindable<?> target = Bindable.of(type).withExistingValue(bean);
			binder.bind(properties.prefix(), target);
			publishBoundEvent(bean, beanName, dataId, groupId, properties, content, configService);
			publishMetadataEvent(bean, beanName, dataId, groupId, properties);
			environment.getPropertySources().remove(name);
		}
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值