@aloxc
2019-11-11T11:18:16.000000Z
字数 4159
阅读 3883
springboot
nacos
如题,我们在使用springcloud的时候直接在maven中添加依赖
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
并且在springboot的配置文件(application.yml)中添加nacos的地址相关配置
spring:
application:
name: dict
cloud:
nacos:
config:
server-addr: 172.16.5.112:9002
shared-dataids: common.yml,${spring.application.name}.yml
refreshable-dataids: common.yml,${spring.application.name}.yml
namespace:
discovery:
server-addr: 172.16.5.112:9002
namespace:
main:
allow-bean-definition-overriding: true
做完这两部就可以使用nacos作为springboot的配置中心和注册中心了。
我们在代码中想使用配置文件中的某个配置直接使用类似下面代码即可
@Value("${zkDevice.backuppath}")
private String backuppath;
这是常规基本操作,nacos中还可以添加
TEXT
JSON
XML
YAML
HTML
Properties
这些类型的配置文件,当我们添加了一个什么文件的时候,我们想读取里面的内容如何办?注意,这个文件可能不是配置文件,比如说我添加了个abc.txt的文件,我们想读取里面的内容如何办?
我们先了解下springboot和nacos是如何集成的,从上面看出来,我们就添加了一点配置就可以使用nacos作为springcloud的注册中心和配置中心,那它是如何工作的?
先了解springboot如何加载远程配置的,springboot提供了加载远程配置的扩展接口,PropertySourceLocator。
那么也就是说nacos实现了其接口NacosPropertySourceLocator
,从NacosPropertySourceLocator
中我们可以看到这样一个属性private NacosPropertySourceBuilder nacosPropertySourceBuilder
,该属性的类是用来读取配置的类,该类中有如下一些代码
private Properties loadNacosData(String dataId, String group, String fileExtension) {
String data = null;
try {
data = configService.getConfig(dataId, group, timeout);
if (!StringUtils.isEmpty(data)) {
log.info(String.format("Loading nacos data, dataId: '%s', group: '%s'",
dataId, group));
if (fileExtension.equalsIgnoreCase("properties")) {
Properties properties = new Properties();
properties.load(new StringReader(data));
return properties;
}
else if (fileExtension.equalsIgnoreCase("yaml")
|| fileExtension.equalsIgnoreCase("yml")) {
YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
yamlFactory.setResources(new ByteArrayResource(data.getBytes()));
return yamlFactory.getObject();
}
}
}
catch (NacosException e) {
log.error("get data from Nacos error,dataId:{}, ", dataId, e);
}
catch (Exception e) {
log.error("parse data from Nacos error,dataId:{},data:{},", dataId, data, e);
}
return EMPTY_PROPERTIES;
}
该方法读取出来的都是都是yaml或者properties这样的配置,我们其实是想读取某个文本文件,怎么办?该方法中有如下代码 configService.getConfig(dataId, group, timeout);
,这个就是读取文件的代码。知道这些逻辑后,整理出一个类,如下(NacosConfig.java),nacos里面有些类的属性是private,使用反射方法读取里面的数据!
import com.alibaba.nacos.api.exception.NacosException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceBuilder;
import org.springframework.cloud.alibaba.nacos.client.NacosPropertySourceLocator;
import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.List;
/**
* nacos工具类
* @author liyh
*/
@Component
@Slf4j
public class NacosConfig {
@Autowired
private PropertySourceBootstrapConfiguration propertySourceBootstrapConfiguration;
/**
* 从nacos中读取某个配置文件的内容
* @param group 对应到nacos中的group组
* @param dataId 对应到nacos中的dataId
* @param timeout
* @return
*/
public String getData(String group,String dataId,long timeout){
try {
Field propertySourceLocators = PropertySourceBootstrapConfiguration.class.getDeclaredField("propertySourceLocators");
propertySourceLocators.setAccessible(true);
List<PropertySourceLocator> list = (List<PropertySourceLocator>)propertySourceLocators.get(propertySourceBootstrapConfiguration);
NacosPropertySourceLocator nacosLocator = null;
for(PropertySourceLocator locator : list){
if(locator instanceof NacosPropertySourceLocator){
nacosLocator = (NacosPropertySourceLocator)locator;
}
}
if(nacosLocator == null){
return null;
}
Field nacosPropertySourceBuilderField = NacosPropertySourceLocator.class.getDeclaredField("nacosPropertySourceBuilder");
nacosPropertySourceBuilderField.setAccessible(true);
NacosPropertySourceBuilder nacosPropertySourceBuilder = (NacosPropertySourceBuilder)nacosPropertySourceBuilderField.get(nacosLocator);
String config = nacosPropertySourceBuilder.getConfigService().getConfig(dataId, group, timeout);
return config;
} catch (NoSuchFieldException | IllegalAccessException | NacosException e) {
log.error("nacos工具异常",e);
}
return null;
}
}