Spring Boot @ConfigurationProperties不从环境中检索属性

2022-09-04 06:02:51

我正在使用Spring Boot 1.2.1,并尝试创建一个具有验证功能的bean,如下所示:@ConfigurationProperties

package com.sampleapp;

import java.net.URL;

import javax.validation.constraints.NotNull;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties
public class SampleAppProperties {
    @NotNull
    private URL url;

    public URL getUrl() {
        return url;
    }
}

引导应用程序的类是:

package com.sampleapp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;

@SpringBootApplication
@EnableConfigurationProperties
public class SampleApplication implements EnvironmentAware {
    private static Logger LOGGER = LoggerFactory.getLogger(SampleApplication.class);

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

    @Override
    public void setEnvironment(Environment environment) {
        LOGGER.info("URL = {}", environment.getRequiredProperty("url"));
    }
}

当我尝试启动此应用程序时,我收到以下异常堆栈:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sampleAppProperties': Could not bind properties to [unknown] (target=, ignoreInvalidFields=false, ignoreUnknownFields=true, ignoreNestedProperties=false); nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'target' on field 'url': rejected value [null]; codes [NotNull.target.url,NotNull.url,NotNull.java.net.URL,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.url,url]; arguments []; default message [url]]; default message [may not be null]
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:303)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:250)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:408)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
    at com.sampleapp.SampleApplication.main(SampleApplication.java:17)
Caused by: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'target' on field 'url': rejected value [null]; codes [NotNull.target.url,NotNull.url,NotNull.java.net.URL,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.url,url]; arguments []; default message [url]]; default message [may not be null]
    at org.springframework.boot.bind.PropertiesConfigurationFactory.validate(PropertiesConfigurationFactory.java:294)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.doBindPropertiesToTarget(PropertiesConfigurationFactory.java:253)
    at org.springframework.boot.bind.PropertiesConfigurationFactory.bindPropertiesToTarget(PropertiesConfigurationFactory.java:225)
    at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization(ConfigurationPropertiesBindingPostProcessor.java:296)
    ... 17 common frames omitted

正如您在上面的方法中看到的那样,我正在记录该属性以验证它是否是 的一部分,并且它显示在异常之前:setEnvironmenturlEnvironment

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.2.1.RELEASE)

2015-02-12 12:32:01.384  INFO 5608 --- [           main] c.s.SampleApplication                    : Starting SampleApplication on VDDK03E-14FB6E5 with PID 5608 (D:\projects\onboarding-parser\target\classes started by .....
2015-02-12 12:32:01.509  INFO 5608 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3252ac20: startup date [Thu Feb 12 12:32:01 EST 2015]; root of context hierarchy
2015-02-12 12:32:03.040  INFO 5608 --- [           main] c.s.SampleApplication                    : URL = http://www.joe.com
2015-02-12 12:32:03.378 ERROR 5608 --- [           main] o.s.b.b.PropertiesConfigurationFactory   : Properties configuration failed validation
2015-02-12 12:32:03.378 ERROR 5608 --- [           main] o.s.b.b.PropertiesConfigurationFactory   : Field error in object 'target' on field 'url': rejected value [null]; codes [NotNull.target.url,NotNull.url,NotNull.java.net.URL,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.url,url]; arguments []; default message [url]]; default message [may not be null]
2015-02-12 12:32:03.394  WARN 5608 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt

将从 中的文件中提取该属性。该文件的内容是:urlapplication.propertiessrc/main/resources

url=http://www.joe.com

答案 1

你的豆子里没有 setter。添加二传手。


答案 2

它清楚地写在这里:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties

Getters 和 setter 通常是强制性的,因为绑定是通过标准的 Java Beans 属性描述符进行的,就像在 Spring MVC 中一样。在某些情况下,可以省略 setter:只要映射被初始化,它们就需要一个 getter,但不一定是 setter,因为它们可以被 binder 突变。可以通过索引(通常使用 YAML)或使用单个逗号分隔值(属性)访问集合和数组。在后一种情况下,setter是强制性的。我们建议始终为此类类型添加 setter。如果初始化集合,请确保它不是不可变的(如上面的示例所示)如果嵌套的 POJO 属性已初始化(如上例中的“安全性”字段),则不需要 setter。如果您希望绑定程序使用其默认构造函数动态创建实例,则需要一个 setter。有些人使用龙目岛计划自动添加获取器和二传手。确保龙目岛不会为此类类型生成任何特定的构造函数,因为容器将自动使用它来实例化对象。


推荐