缘起 :项目需读取nacos中动态的TDengine数据库连接信息并提取IP,一个并不复杂的操作,但作为一个nacos知识浅薄的菜鸡,我愣是捯饬了几个小时……惭愧惭愧……
异常代码
@Data
@Component
public class TaosLink {
// @Value("${spring.datasource.dynamic.datasource.taos.url}")
@Value("${spring.datasource.tdengine.datasource.jdbc-url}")
private String url;
}
报错信息
报错核心:
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder ‘spring.datasource.tdengine.datasource.jdbc-url’ in value “${spring.datasource.tdengine.datasource.jdbc-url}”
具体报错:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'handleData' defined in file [E:\3H1Work\WanRuiIOT\iot-platform\blade-service\dl-iot-manager\target\classes\org\springblade\modules\component\netty\ws\service\HandleData.class]: Unsatisfied dependency expressed through constructor parameter 4; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'environmentalKrDeviceServiceImpl' defined in file [E:\3H1Work\WanRuiIOT\iot-platform\blade-service\dl-iot-manager\target\classes\org\springblade\modules\dataScreen\service\impl\EnvironmentalKrDeviceServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 7; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'purityAnalysisServiceImpl' defined in file [E:\3H1Work\WanRuiIOT\iot-platform\blade-service\dl-iot-manager\target\classes\org\springblade\modules\dataScreen\service\impl\PurityAnalysisServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 5; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'taosLink': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.tdengine.datasource.jdbc-url' in value "${spring.datasource.tdengine.datasource.jdbc-url}"
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:164)
at org.springblade.core.launch.BladeApplication.run(BladeApplication.java:50)
异常原因
以上报错通常是由于配置文件异常导致的,即没有找到对应的配置信息。首先我们需要查看当前模块的nacos配置信息,并核验当前nacos所处的命名空间是否包含以上异常代码中的配置属性。
排查过程
- 1、查看nacos配置信息(group为
dl-iot-manage
)
- 2、根据nacos配置信息核验需属性是否在对应的配置文件内(nacos中
spring.datasource.tdengine.datasource.jdbc-url
所属配置的group为dl-iot-link
与 项目的nacos配置不同,即产生异常的根本原因, 修改项目中nacos配置信息或将所需的配置属性添加到nacos配置信息指定的配置文件,即可解决异常)
-
3、将配置属性地址修改为项目nacos配置中指定的命名空间和组,然后重启,报错消失
-
无异常代码
@Data @Component public class TaosLink { @Value("${spring.datasource.dynamic.datasource.taos.url}") private String url; }
-
与项目中nacos配置匹配的命名空间和组
-
-
解析配置属性,提取IP地址
// 注入配置所属的类 @Resource private final TaosLink taosLink; public String getTaosUrl(){ String url = taosLink.getUrl(); // 提取IP地址的正则表达式 String regex = "((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(url); String group = ""; if (matcher.find()){ group = matcher.group(); } log.info("IP信息: " + group); return String.format(IotRedisContant.TAOS_URL, group); }
-
运行结果
项目中nacos配置正常仍无法获取属性
确认项目中nacos的配置和nacos中yaml文件的基础信息无误后仍无法读取指定属性值,建议检查项目运行时本地生成的yaml文件,查看文件中是否含有所需属性。如果本地不存在yaml文件则说明nacos连接信息有误,需检查nacos的运行状况;如果本地存在yaml文件但文件中没有所需属性,则说明nacos中部署的配置文件不含所需属性。本地生成的文件地址如下:
-
项目运行产生的nacos文件夹
-
文件夹中生成的yaml文件