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
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 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
})
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
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();
}
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
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"
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.
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
Source: Stackoverflow.com