创建 Bean 错误(Spring Cloud Config 客户端)

Error Creating Bean Error (Spring Cloud Config Client)

我正在尝试学习 Spring Cloud Config。所以首先我设置了一个服务器,我可以在其中使用浏览器上的 http://localhost:9090/config/default/master/app.static.properties 获取属性。它有大约 5 或 6 个属性。我现在想买一个。

我写了我的 类 喜欢:

package com.gcp.logicalprovisioning.config.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class DemoClientApplication {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoClientApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoClientApplication.class, args);
    }


    /**
     * Output property from cloud-config-server on startup of app,
     *
     * also can be seen at:
     * http://localhost:9090/env/APP.aaf.env
     */
    @Bean
    public CommandLineRunner printProperties(@Value("${APP.aaf.env}") final String appProperty)  {
        return args -> LOGGER.info("APP.aaf.env is: [{}]", appProperty);
    }
}

package com.gcp.logicalprovisioning.config.server;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
// This will allow us to reinitialize this controller to get any new config
// values when the /refresh endpoint is POSTed to.
@RefreshScope

public class DemoClientController {

    @Value("${APP.aaf.env}")
    private String appProperty;

    @RequestMapping("/")
    public String hello() {
        return "Using [" + appProperty + "] from config server";
    }
}

我的 bootstrap.properties 看起来像:

spring.application.name=client
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:9090/config/default/master/
spring.cloud.config.enabled=true
spring.security.user.name=admin
spring.security.user.password=admin
logging.level.web=DEBUG
debug=false
spring.output.ansi.enabled=ALWAYS
spring.devtools.restart.enabled=true
spring.config.import=optional:configserver:http://localhost:9090/
spring.cloud.config.import-check.enabled=false

但是我得到这个错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'printProperties' defined in com.gcp.logicalprovisioning.config.server.DemoClientApplication: Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'APP.aaf.env' in value "${APP.aaf.env}"
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=14=](AbstractBeanFactory.java:335) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) [spring-boot-2.5.3.jar:2.5.3]
    at com.att.logicalprovisioning.config.server.DemoClientApplication.main(DemoClientApplication.java:20) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_281]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_281]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_281]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_281]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.5.3.jar:2.5.3]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'APP.aaf.env' in value "${APP.aaf.env}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties[=14=](PropertySourcesPlaceholderConfigurer.java:175) ~[spring-context-5.3.9.jar:5.3.9]

我在Whosebug上搜索了这个问题,找到了几个解决方案,试了一下。但没有任何效果。但是由于我弄湿了脚,所以我不确定出了什么问题。我是否缺少一些额外的配置?任何帮助将不胜感激。

我还没有发布我的服务器代码,如果需要请告诉我,我会添加它。

请注意,Spring 云配置服务器客户端将为您构建应用程序配置文件特定配置的完整路径。因此,您应该只在 bootstrap.properties 中提供基数 URL。在你的情况下,这可能是这样的:

spring.cloud.config.uri=http://localhost:9090/

是的,正如 Gregor Zurowski 所建议的那样,您可以使用本机配置文件并为包含属性的 properties/yaml 文件提供适当的命名。 注意:如果您使用基于本机的配置文件,Spring 云配置服务器应提供“spring.cloud.config.server.native.search-位置”。

在 Gregor 的帮助下,我能够解决它。这些是我所做的更改:

我加了一个messageConverter:

package com.gcp.logicalprovisioning.config.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class DemoClientApplication {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoClientApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoClientApplication.class, args);
    }


    /**
     * Output property from cloud-config-server on startup of app,
     *
     * also can be seen at:
     * http://localhost:9090/env/APP.aaf.env
     */
    @Bean
    public CommandLineRunner printProperties(@Value("${APP.aaf.env}") final String appProperty)  {
        return args -> LOGGER.info("APP.aaf.env is: [{}]", appProperty);
    }
    
    @Bean
    public RestTemplate restTemplate() {

        final RestTemplate restTemplate = new RestTemplate();

        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();

        mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));

        messageConverters.add(mappingJackson2HttpMessageConverter);

        restTemplate.setMessageConverters(messageConverters);

        return restTemplate;
    }
}

并且在 bootstrap.properties 中也添加了一些额外的配置:

debug=false
logging.level.web=DEBUG
server.port=1010
spring.application.name=app.static
spring.cloud.config.uri=http://localhost:9090/
spring.cloud.config.username=admin
spring.cloud.config.password=admin
spring.cloud.config.enabled=true
spring.cloud.config.import-check.enabled=false
spring.devtools.restart.enabled=true
spring.output.ansi.enabled=ALWAYS
spring.security.user.name=admin
spring.security.user.password=admin

现在我可以使用 URL http://localhost:9090/app.static/default

从配置服务器获取配置

简而言之:

  1. 我必须添加 messageConverter。
  2. 更改 git.config.uri.
  3. 并将 username/password 添加到 bootstrap.properties,因为配置服务器与 username/password 绑定。
  4. 删除 spring.config.import 属性。

@SpringBootApplication 内添加 scanBasePackages,如下所示:

@SpringBootApplication(scanBasePackages =
    {
        "com.gcp.logicalprovisioning.config",
        ....etc
    })