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.