Issue
I currently have a microservice in Spring Boot, where I have some properties stored in application.properties. Right now, it is configured for one store only. But I want to change the logic so that stores can be added dynamically without needing to change any code.
I have created a model java class for a store, and it looks like this:
public class Store {
private String username;
private String password;
private String hostname;
private int port;
}
My application.properties looks like this today:
system.connection.username=TestUser
system.connection.password=123456
system.connection.hostname=12.34.56.78
system.connection.port=1234
But I want to be able to specify which store it is, and be able to add more stores by just adding them into the application.properties, like this:
system.connection.Store1.username=TestUser1
system.connection.Store1.password=123456
system.connection.Store1.hostname=12.34.56.78
system.connection.Store1.port=1234
system.connection.Store2.username=TestUser2
system.connection.Store2.password=859382
system.connection.Store2.hostname=34.34.34.34
system.connection.Store2.port=4444
Then add this into some hashmap, and be able to check for and retrieve the variables for a specific store from any of my other classes.
For this, I have tried the following:
@Configuration
@ConfigurationProperties(prefix = "system.connection")
class StoresConfiguration(
val stores: HashMap<String, Store> = HashMap()
) {
fun getStore(storeName: String): Store? {
return stores.get(storeName)
}
}
But getStore only returns null, and even if I check stores.size it is 0. So where am I doing wrong, and how can I do this effectively? I have thought about just skipping the crap and just making a folder called "stores" and put json files in it, and read from there. So that each Store is just a json file, so at startup the app scans the folder and for every json file makes a Store object. But I don't know if that is a good solution. This is my first time working with Spring Boot. Thanks for any help!
Solution
By playing around a little bit, I managed to solve the issue. I reverted my class back to Kotlin, and made some adjustments on how I retrieve the values. This is how you can load dynamic objects from application.properties in Spring Boot with Kotlin:
Suppose you have an object class called Store.kt
data class Store(
var name: String ?= null,
var username: String ?= null,
var password: String ?= null,
var hostname: String ?= null,
var port: Int ?= null,
)
In your application.properties
system.stores.Store1.name=Test1
system.stores.Store1.username=test1
system.stores.Store1.password=123456
system.stores.Store1.hostname=12.34.56.78
system.stores.Store1.port=1234
system.stores.Store2.name=Test2
system.stores.Store2.username=test2
system.stores.Store2.password=123456
system.stores.Store2.hostname=12.34.56.78
system.stores.Store2.port=1234
This is in your StoresConfiguration.kt
@Configuration
@ConfigurationProperties(prefix = "system")
class StoreConfiguration(
var stores: HashMap<String, Store> = HashMap()
) {
fun getStore(storeName: String) : Store? {
return stores.get(storeName)
}
}
Then suppose you want to get the objects and use them in one of your service classes:
@Service
class StoreService(
private val storeConfiguration: StoreConfiguration,
) {
fun test() {
val MyStore = storeConfiguration.getStore("Store1")
if (MyStore != null) {
// Do whatever you want to do with your object
} else {
// If your object does not exist
}
}
}
Answered By - Crystalii