I am working on a Spring Boot Java project.
I’ll firstly explain how I handled a similar situation of my problem, and secondly, the problem itself.
A similar situation of my problem I correctly handled
I needed to get some API URLs which depends from the environment (test/prod), so I’ve decided to get these from (application-test/application-prod).properties files in combination with @Configuration
@ConfigurationProperties
annotations and ${spring.profiles.active}
environment variable. I knew I could have the URLs in the application initialization, so, relying on Spring dependency management was the best idea to do the job (simply put, Spring Boot injects these properties before the application starts and that’s what I wanted).
The problem
I need to read some new parameters I can store in a .properties file (not the “older” ones application[-{env}].properties), but now, the difference is that I can only know which properties file I have to read after I read a request parameter, not before the application starts anymore. And most importantly, the class that should read this .properties file is not a Spring managed class. A MWE:
@Configuration
@ConfigurationProperties
@PropertySource("classpath:INAD/INAD-${spring.profiles.active}.properties")
public class MyInitializationConfig{
private String var;
// var getter/setter
}
@RestController
public class MyController{
@Autowired
MyService myService;
@Autowired
MyInitializationConfig myInitializationConfig;
@PostMapping("/endpoint")
public void endpoint(@RequestBody MyRequest myRequest){
// here, I can get the initialized properties:
myInitializationConfig.getProperties("configprop");
myService.serviceMethod(myRequest);
}
}
@Service
public class MyService{
@Autowired
MyInitializationConfig myInitializationConfig;
public void serviceMethod(MyRequest myRequest){
// here, I can get initialized properties, too:
myInitializationConfig.getProperties("configprop");
MyEntity myEntity = new MyEntity(myRequest);
myEntity.entityMethod();
}
}
// Has no Spring Boot annotations
public class MyEntity{
private MyRequest myRequest;
public MyEntity(MyRequest myRequest){
this.myRequest = myRequest;
}
public void entityMethod(){
// here, I would like to retrieve some .properties (not the initialized ones with MyInitializationConfig) values
}
}
My solutions
Note that:
- (again) The problem is
MyEntity
(precisely,MyEntity.entitymethod()
), whileMyInitializationConfig
is not the object of the problem, with that, I just wanted to show how I handled something similar to the problem I’m asking. MyEntity
has not to be a singleton, it’s something I have to instantiate more times.MyEntity
constructor should remain as I wrote, i.e. with only theMyRequest
object parameter, by logic, and for testing purposes.
So: do you agree I can’t read these property values with Spring Boot injections (e.g. by using something like @Value in MyEntity) anymore, because, as it is currently written, MyEntity
is a simply new
Java object? If not, how can I use some Spring Boot injections that doesn’t require to inject something at the application initialization time, in your opinion?
Finally, I thought at two solutions:
- Using ordinary Java file-reading APIs, something like:
new Properties().load(new FileInputStream("path/to/config.properties"))
- Using Spring Boot file-reading APIs, I’ve read classes such
org.springframework.core.io.DefaultResourceLoader