Spring Boot application.properties值未填充


96

我有一个非常简单的Spring Boot应用程序,正在尝试使用某些外部化配置。我尝试遵循spring boot文档中的信息,但是遇到了障碍。

当我在外部运行以下应用程序时,application.properties文件中的外部配置不会填充到Bean中的变量中。我确定我做的很蠢,谢谢您的建议。

MyBean.java(位于/ src / main / java / foo / bar /中)

package foo.bar;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    @Value("${some.prop}")
    private String prop;

    public MyBean() {
        System.out.println("================== " + prop + "================== ");
    }
}

Application.java(位于/ src / main / java / foo /中)

package foo;

import foo.bar.MyBean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

    @Autowired
    private MyBean myBean;

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

application.properties(位于/ src / main / resources /中)

some.prop=aabbcc

执行Spring Boot应用程序时的日志输出

grb-macbook-pro:properties-test-app grahamrb$ java -jar ./build/libs/properties-test-app-0.1.0.jar

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

2014-09-10 21:28:42.149  INFO 16554 --- [           main] foo.Application                          : Starting Application on grb-macbook-pro.local with PID 16554 (/Users/grahamrb/Dropbox/dev-projects/spring-apps/properties-test-app/build/libs/properties-test-app-0.1.0.jar started by grahamrb in /Users/grahamrb/Dropbox/dev-projects/spring-apps/properties-test-app)
2014-09-10 21:28:42.196  INFO 16554 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e38ec8: startup date [Wed Sep 10 21:28:42 EST 2014]; root of context hierarchy
2014-09-10 21:28:42.828  INFO 16554 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2014-09-10 21:28:43.592  INFO 16554 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-09-10 21:28:43.784  INFO 16554 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2014-09-10 21:28:43.785  INFO 16554 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.54
2014-09-10 21:28:43.889  INFO 16554 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-09-10 21:28:43.889  INFO 16554 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1695 ms
2014-09-10 21:28:44.391  INFO 16554 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-09-10 21:28:44.393  INFO 16554 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
================== null==================
2014-09-10 21:28:44.606  INFO 16554 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.679  INFO 16554 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2014-09-10 21:28:44.679  INFO 16554 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2014-09-10 21:28:44.716  INFO 16554 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.716  INFO 16554 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.902  INFO 16554 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2014-09-10 21:28:44.963  INFO 16554 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-09-10 21:28:44.965  INFO 16554 --- [           main] foo.Application                          : Started Application in 3.316 seconds (JVM running for 3.822)
^C2014-09-10 21:28:54.223  INFO 16554 --- [       Thread-2] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e38ec8: startup date [Wed Sep 10 21:28:42 EST 2014]; root of context hierarchy
2014-09-10 21:28:54.225  INFO 16554 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

4
以及@Value在构造bean之前应如何更换?您“检测”该值是否设置的方式是错误的。在那一刻,它始终为null,这@Value将在对象构造后进行处理。
M. Deinum 2014年

Answers:


163

您执行属性注入的方式将不起作用,因为注入是在调用构造函数之后完成的。

您需要执行以下操作之一:

更好的解决方案

@Component
public class MyBean {

    private final String prop;

    @Autowired
    public MyBean(@Value("${some.prop}") String prop) {
        this.prop = prop;
        System.out.println("================== " + prop + "================== ");
    }
}

可行的解决方案,但测试性较差,可读性较差

@Component
public class MyBean {

    @Value("${some.prop}")
    private String prop;

    public MyBean() {

    }

    @PostConstruct
    public void init() {
        System.out.println("================== " + prop + "================== ");
    }
}

还要注意,它不是特定于Spring Boot的,而是适用于任何Spring应用程序


我有一个@Autowired注解添加到构造,使其工作
塞巴斯蒂安·特龙普

1
谢谢你的提示。这应该在Spring文档中讨论@Value注释的地方-但是那些家伙似乎对他们的文档反馈不感兴趣:(
Alex Worden 2015年

1
节省了我一些烦恼。谢谢!
罗伯特·莫斯卡尔

1
@geoand如果您有10个以上的值,那您将不得不像以前那样输入所有10个值吗?还是有更清洁的方法
Jesse

1
@Jackie确实有一种更清洁的方法!@ConfigurationProperties@EnableConfigurationProperties

5

用户“ geoand”在这里指出原因并给出解决方案是正确的。但是更好的方法是将配置封装到一个单独的类中,例如SystemContiguration java类,然后将该类注入到您想使用这些字段的任何服务中。

您当前将配置值直接读取到服务中的方式(@grahamrb)容易出错,如果更改了配置设置名称,将导致重构麻烦。


如果您拥有该物业的单独班级,怎么会再没有那么头疼的事了?重构时您仍然需要记住一个字符串
dot_Sp0T

4
您只需要记住一个地方,而不是N号。SystemContiguration上存在的标量值使您可以进行强类型输入。同样,如果有基于“来自配置”的值的“分叉”业务逻辑,则最好向需要该值的类/ businessLogic中注入一些东西。再次,模拟SystemContiguration然后尝试让@Value在所有地方正常工作要容易得多。
granadaCoder

3

实际上,下面对我来说效果很好。

@Component
public class MyBean {

   public static String prop;

   @Value("${some.prop}")
   public void setProp(String prop) {
      this.prop= prop;
   }

   public MyBean() {

   }

   @PostConstruct
   public void init() {
      System.out.println("================== " + prop + "================== ");
   }

}

现在,无论我想要什么,只要调用

MyBean.prop

它将返回值。


2

这个答案可能适用于您的情况,也可能不适用于您的情况...一旦出现类似症状,并且多次仔细检查了代码,一切看起来都不错,但@Value设置仍然没有生效。然后在File > Invalidate Cache / Restart处理IntelliJ完我(我的IDE)之后,问题就消失了……

这很容易尝试,因此值得一试


1

使用环境类,我们可以获得应用程序。属性值

@Autowired,

private Environment env;

和访问使用

String password =env.getProperty(your property key);

0

跟着这些步骤。1:-创建您的配置类,如下所示

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;

@Configuration
public class YourConfiguration{

    // passing the key which you set in application.properties
    @Value("${some.pro}")
    private String somePro;

   // getting the value from that key which you set in application.properties
    @Bean
    public String getsomePro() {
        return somePro;
    }
}

2:-如果拥有配置类,则从所需的配置中注入变量。

@Component
public class YourService {

    @Autowired
    private String getsomePro;

    // now you have a value in getsomePro variable automatically.
}

0

如果您正在处理具有多个不同application.properties文件的大型多模块项目,请尝试将值添加到项目的属性文件中。

如果不确定哪个项目是父项目,请检查项目pom.xml文件中是否有<parent>标签。

这为我解决了这个问题。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.