简体   繁体   English

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

[英]Spring Boot @ConfigurationProperties not retrieving properties from Environment

I'm using Spring Boot 1.2.1 and trying to create a @ConfigurationProperties bean with validation like so: 我正在使用Spring Boot 1.2.1并尝试创建一个带有验证的@ConfigurationProperties bean,如下所示:

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;
    }
}

The class to bootstrap the application is: 引导应用程序的类是:

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"));
    }
}

When I try and start this application I receive the following exception stack: 当我尝试启动此应用程序时,我收到以下异常堆栈:

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

As you can see in the setEnvironment method above I'm logging the url property to validate that it's part of the Environment and it is displayed before the exception: 正如您在上面的setEnvironment方法中所看到的,我正在记录url属性以验证它是Environment的一部分并且它在异常之前显示:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: 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

The url property is pulled from the application.properties file in src/main/resources . url属性是从src/main/resourcesapplication.properties文件中提取的。 The contents of the file are: 该文件的内容是:

url=http://www.joe.com

There's no setter in your bean. 你的bean中没有setter。 Add a setter. 添加一个setter。

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

Getters and setters are usually mandatory, since binding is via standard Java Beans property descriptors, just like in Spring MVC. getter和setter通常是必需的,因为绑定是通过标准的Java Beans属性描述符,就像在Spring MVC中一样。 There are cases where a setter may be omitted: Maps, as long as they are initialized, need a getter but not necessarily a setter since they can be mutated by the binder. 有些情况下可能会省略一个setter:只要它们被初始化,就需要一个getter但不一定是setter,因为它们可以被绑定器变异。 Collections and arrays can be either accessed via an index (typically with YAML) or using a single comma-separated value (properties). 可以通过索引(通常使用YAML)或使用单个逗号分隔值(属性)访问集合和数组。 In the latter case, a setter is mandatory. 在后一种情况下,必须设置一个setter。 We recommend to always add a setter for such types. 我们建议始终为这些类型添加setter。 If you initialize a collection, make sure it is not immutable (as in the example above) If nested POJO properties are initialized (like the Security field in the example above), a setter is not required. 如果初始化集合,请确保它不是不可变的(如上例所示)如果初始化嵌套的POJO属性(如上例中的“安全性”字段),则不需要setter。 If you want the binder to create the instance on-the-fly using its default constructor, you will need a setter. 如果您希望绑定器使用其默认构造函数即时创建实例,则需要一个setter。 Some people use Project Lombok to add getters and setters automatically. 有些人使用Project Lombok自动添加getter和setter。 Make sure that Lombok doesn't generate any particular constructor for such type as it will be used automatically by the container to instantiate the object. 确保Lombok不为此类型生成任何特定构造函数,因为容器将自动使用它来实例化对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM