I have a very simple configuration and a big confusion that I need help resolving.
I have a BaseController which is annotated with @RestController. In this class I have a method that returns a String and is annotated with @GetMapping. I am reading properties file from it and displaying the application value. Till here, all works GOOD. Below are my files,
@RestController
public class BaseController {
@Autowired
Environment env;
@GetMapping("/hello")
public String hello() {
String myAppName = env.getProperty("spring.application.name");
return "From Controller -> " + myAppName;
}
}
My application.properties file,
server.servlet.context-path=/BootEnv
server.port=8085
spring.application.name=EnvironmentAPITester
When I hit,
, I get proper response like below,
From Controller -> EnvironmentAPITester
Here in code, Environment variable is org.springframework.core.env.Environment;
All is GOOD till here.
Now I have created a new @Configuration class named ApplicationConfig. I want to read the properties file from that class as well and return the values. So below are the changes I did,
@RestController
public class BaseController {
@Autowired
Environment env;
@GetMapping("/hello")
public String hello() {
String myAppName = env.getProperty("spring.application.name");
return "From Controller -> " + myAppName;
}
@GetMapping("/helloConf")
public String getDetails() {
ApplicationConfig conf = new ApplicationConfig();
String fromConfig = conf.details();
return "From Config -> "+fromConfig;
}
}
And the class below,
@Configuration
public class ApplicationConfig{
@Autowired
Environment env;
public String details() {
return env.getProperty("spring.application.name");
}
}
Now when I hit,
I get a null pointer exception as the Environment variable is null and does NOT get auto configured. HOW? And WHY?
After googling, I came to a solution which asked me to implement EnvironmentAware interface and set the Environment variable that way. So below are the changes I had to make to my ApplicationConfig class,
@Configuration
public class ApplicationConfig implements EnvironmentAware{
@Autowired
Environment env;
public String details() {
return env.getProperty("spring.application.name");
}
@Override
public void setEnvironment(Environment environment) {
this.env = environment;
}
}
After doing this also, it still gave me null pointer exception for the same Environment variable value. Then I figured out that not only I had to remove the @Autowire annotation but I ALSO needed to make that variable static to make it work. So when I do,
//@Autowired
static Environment env;
It works perfectly. And when I hit,
I get proper response,
From Config -> EnvironmentAPITester
The confusion is WHY do I need to make it static so that it fills the value? Why the EnvironmentAware implementation can't set the Environment variable while it is still @Autowired?
And why in the first place, @Autowired does not fill the Environment variable when the class ApplicationConfig class is marked with @Configuration annotation? Even if I change this class annotation to @Service or @Repository or @Component the same issue persists of failing to@Autowire the Environment variable. How come?
I know it's a long post. But any clarification on this is highly appreciated as I am having hard time understanding this.
Thanks for your help in advance.