Java Spring Boot @ConfigurationProperties 不从 Environment 检索属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28485442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot @ConfigurationProperties not retrieving properties from Environment
提问by Centinul
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.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
. The contents of the file are:
该url
属性是从拉application.properties
文件src/main/resources
。该文件的内容是:
url=http://www.joe.com
采纳答案by Dave Syer
There's no setter in your bean. Add a setter.
你的 bean 中没有 setter。添加一个二传手。
回答by karibe50
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. 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. Collections and arrays can be either accessed via an index (typically with YAML) or using a single comma-separated value (properties). In the latter case, a setter is mandatory. We recommend to always add a setter for such types. 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. If you want the binder to create the instance on-the-fly using its default constructor, you will need a setter. Some people use Project Lombok to add getters and setters automatically. 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.
Getter 和 setter 通常是强制性的,因为绑定是通过标准的 Java Beans 属性描述符进行的,就像在 Spring MVC 中一样。在某些情况下可以省略 setter:Maps,只要它们被初始化,就需要一个 getter,但不一定需要一个 setter,因为它们可以被绑定器改变。可以通过索引(通常使用 YAML)或使用单个逗号分隔值(属性)访问集合和数组。在后一种情况下,setter 是强制性的。我们建议始终为此类类型添加 setter。如果您初始化一个集合,请确保它不是不可变的(如上例所示) 如果初始化了嵌套的 POJO 属性(如上例中的 Security 字段),则不需要设置器。如果您希望活页夹使用其默认构造函数即时创建实例,则需要一个 setter。有些人使用 Project Lombok 自动添加 getter 和 setter。确保 Lombok 不会为此类类型生成任何特定的构造函数,因为容器将自动使用它来实例化对象。