I have a Spring Boot application and in one of the classes, I try to reference a property from the application.properties file using @Value
. But, the property does not get resolved. I have looked at similar posts and tried following the suggestions, but that didn't help. The class is:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class PrintProperty {
@Value("${file.directory}")
private String fileDirectory;
public void print() {
System.out.println(fileDirectory);
}
}
I have the property file.directory in application.properties
. I have other fields as well.
This question is related to
spring
spring-boot
spring-annotations
To read the values from application.properties we need to just annotate our main class with @SpringBootApplication
and the class where you are reading with @Component or variety of it. Below is the sample where I have read the values from application.properties
and it is working fine when web service is invoked. If you deploy the same code as is and try to access from http://localhost:8080/hello you will get the value you have stored in application.properties for the key message.
package com.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
@Value("${message}")
private String message;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@RequestMapping("/hello")
String home() {
return message;
}
}
Try and let me know
I´d like to mention, that I used spring boot version 1.4.0 and since this version you can only write:
@Component
public class MongoConnection {
@Value("${spring.data.mongodb.host}")
private String mongoHost;
@Value("${spring.data.mongodb.port}")
private int mongoPort;
@Value("${spring.data.mongodb.database}")
private String mongoDB;
}
Then inject class whenever you want.
EDIT:
From nowadays I would use @ConfigurationProperties because you are able to inject property values in your POJOs. Keep hierarchical sort above your properties. Moreover, you can put validations above POJOs attributes and so on. Take a look at the link
I had the same problem like you. Here's my error code.
@Component
public class GetExprsAndEnvId {
@Value("hello")
private String Mysecret;
public GetExprsAndEnvId() {
System.out.println("construct");
}
public void print(){
System.out.println(this.Mysecret);
}
public String getMysecret() {
return Mysecret;
}
public void setMysecret(String mysecret) {
Mysecret = mysecret;
}
}
This is no problem like this, but we need to use it like this:
@Autowired
private GetExprsAndEnvId getExprsAndEnvId;
not like this:
getExprsAndEnvId = new GetExprsAndEnvId();
Here, the field annotated with @Value is null because Spring doesn't know about the copy of GetExprsAndEnvId that is created with new and didn't know to how to inject values in it.
Make sure your application.properties file is under src/main/resources/application.properties. Is one way to go. Then add @PostConstruct as follows
Sample Application.properties
file.directory = somePlaceOverHere
Sample Java Class
@ComponentScan
public class PrintProperty {
@Value("${file.directory}")
private String fileDirectory;
@PostConstruct
public void print() {
System.out.println(fileDirectory);
}
}
Code above will print out "somePlaceOverhere"
Your problem is that you need a static
PropertySourcesPlaceholderConfigurer
Bean definition in your configuration. I say static with emphasis, because I had a non-static one and it didn't work.
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
You haven't included package declarations in the OP but it is possible that neither @SpringBootApplication
nor @ComponentScan
are scanning for your @Component
.
The @ComponentScan
Javadoc states:
Either
basePackageClasses
orbasePackages
(or its aliasvalue
) may be specified to define specific packages to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.
ISTR wasting a lot of time on this before and found it easiest to simply move my application class to the highest package in my app's package tree.
More recently I encountered a gotcha were the property was being read before the value insertion had been done. Jesse's answer helped as @PostConstruct
seems to be the earliest you can read the inserted values, and of course you should let Spring call this.
I had the similar issue and the above examples doesn't help me to read properties. I have posted the complete class which will help you to read properties values from application.properties file in SpringBoot application in the below link.
Spring Boot - Environment @Autowired throws NullPointerException
I had the same issue get value for my property in my service class. I resolved it by using @ConfigurationProperties instead of @Value.
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "file")
public class FileProperties {
private String directory;
public String getDirectory() {
return directory;
}
public void setDirectory(String dir) {
this.directory = dir;
}
}
@EnableConfigurationProperties({
FileProperties.class
})
Source: Stackoverflow.com