Properties 值未填充

我有一个非常简单的 SpringBoot 应用程序,我正在尝试使用一些外部配置。我试图跟踪 弹簧启动文档上的信息,但是我遇到了一个障碍。

当我在 application.properties 文件中的外部配置下运行应用程序时,它不会被填充到 bean 中的变量中。我肯定做了什么蠢事,谢谢你的建议。

MyBean.java (located in /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 (located in /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
182187 次浏览

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

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

Better solution

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

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

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

当前(@grahamrb)将配置值直接读入服务的方法很容易出错,如果更改配置设置名称,将引起重构问题。

事实上,对我来说,下面的工作很好。

@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

它将返回值。

This answer may or may not be applicable to your case ... Once I had a similar symptom and I double checked my code many times and all looked good but the @Value setting was still not taking effect. And then after doing File > Invalidate Cache / Restart with my IntelliJ (my IDE), the problem went away ...

这是非常容易尝试,所以可能是值得一试

使用 Environment 类我们可以得到 application.Properties 值

@Autowired,

private Environment env;

以及使用

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

follow these steps. 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.
}

如果您正在使用几个不同的 application.properties文件处理一个大型多模块项目,那么尝试将您的值添加到 家长项目的属性文件中。

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

这对我来说解决了问题。

你可以使用 Environment类来获取数据:

@Autowired
private Environment env;
String prop= env.getProperty('some.prop');

为我解决这个问题的最简单的方法是:

向需要填充 @Value字段的 Component/Service 添加 @PropertySource注释:

@Service
@PropertySource("classpath:myproperties.properties")
public class MyService {


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


// some logic...
}

确保将属性文件添加到与服务/组件相同的模块的资源文件夹中。

之所以出现这个错误,是因为您正在用 new 关键字初始化该类, 首先,您需要创建配置类,在这个类下,您需要创建这个类的 bean。 When you will call it by using bean then it will work..

package ca.testing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;


import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.DriverManager;


@Component
@PropertySource("db.properties")
public class ConnectionFactory {
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
Connection connection;


public Connection getConnection(){
try {
connection = DriverManager.getConnection(url, user, password);
System.out.println(connection.hashCode());
}catch (Exception e){
System.out.println(e);
}
return connection;
}


public static void main(String[] args) {
AnnotationConfigApplicationContext context= new AnnotationConfigApplicationContext(Config.class);
ConnectionFactory connectionFactory= context.getBean(ConnectionFactory.class);
connectionFactory.getConnection();
}
}

我的应用程序属性是在我从不同的类(如(new Bean ())中删除关键字 new 之后挑选的

没有将参数构造函数代码移动到 PostConstruction 已经完成了这个技巧 对我来说。因为它将保持默认的 bean 加载工作流完整无缺。

@Component
public class MyBean {


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


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