这个适合新版本的springcloud,且整个配置获取不到的问题,如果着急看结果的朋友,划到最后
今天在体验spring-cloud的时候,发现一个问题,就是com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository报了spring.application.name找不到,
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.application.name' in value "${spring.application.name}"
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:405) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1415) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:608) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.3.jar:5.3.3]
... 19 common frames omitted
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.application.name' in value "${spring.application.name}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:178) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-5.3.3.jar:5.3.3]
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175) ~[spring-context-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:936) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1321) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.3.jar:5.3.3]
... 31 common frames omitted
配置文件如下
之后排查原因,发现其实spring.profiles.active也没有获取到,那么初步判断整个文件都没有获取到,spring-boot在读取文件的时候,会使用yaml的组件进行读取,之后排查该组件的读取内容,发现bootstrap没有读取到,只读取了application的文件
spring-boot有一个配置,是读取配置文件名的,叫做spring.config.name,这个配置决定spring-boot读取哪些配置名的文件,如果读取不到,默认读取application的文件
那么在这里初步排查为没有读取到这个配置,之后排查将bootstrap写入这个配置的地方,在一个叫做BootstrapApplicationListener的类中,有一个方法使用了,并且将其写入到ApplicationEnvironmentPreparedEvent的配置变量中,这里的配置变量,也就是之后springboot在注入@Value值会寻找配置key的地方
那么要解决的是,怎么将bootstrap加入到这里边
在springboot启动的时候会发布启动事件,BootstrapApplicationListener监听的ApplicationEnvironmentPreparedEvent事件发布之后,那么就会触发BootstrapApplicationListener的事件监听执行
这里的BootstrapApplicationListener会判断是否开启bootstrap配置,配置key叫spring.cloud.bootstrap.enabled,这里我用的是比较新版本的springcloud,这里的bootstrap配置是默认关闭的,所以会导致获取不到bootstrap的配置文件
到这里基本上就排查完毕了,那么要做的是,启动的时候将这个配置加上,我的做法是在main方法启动的时候,将这个配置设为true,这样默认就启动了
public static void main(String[] args) {
args = Arrays.copyOf(args, args.length + 1);
args[args.length - 1] = "--spring.cloud.bootstrap.enabled=true";
SpringApplication.run(OrderApplication.class,args);
}