【问题标题】:Load dynamic objects from application.properties in Spring Boot在 Spring Boot 中从 application.properties 加载动态对象
【发布时间】:2022-01-03 21:48:25
【问题描述】:

我目前在 Spring Boot 中有一个微服务,其中一些属性存储在 application.properties 中。目前,它仅配置为一个商店。但是我想更改逻辑,以便可以动态添加商店而无需更改任何代码。

我为商店创建了一个模型 java 类,它看起来像这样:

public class Store {
    private String username;
    private String password;
    private String hostname;
    private int port;
}

我的 application.properties 今天看起来像这样:

system.connection.username=TestUser
system.connection.password=123456
system.connection.hostname=12.34.56.78
system.connection.port=1234

但我希望能够指定它是哪个商店,并且能够通过将它们添加到 application.properties 中来添加更多商店,如下所示:

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

然后将其添加到一些哈希图中,并能够从我的任何其他类中检查和检索特定商店的变量。

为此,我尝试了以下方法:

@Configuration
@ConfigurationProperties(prefix = "system.connection")
class StoresConfiguration(
    val stores: HashMap<String, Store> = HashMap()
) {

    fun getStore(storeName: String): Store? {
        return stores.get(storeName)
    }


}

但是getStore 只返回null,即使我检查stores.size 它也是0。那么我在哪里做错了,我怎样才能有效地做到这一点?我考虑过跳过废话,只创建一个名为“stores”的文件夹并将 json 文件放入其中,然后从那里读取。这样每个 Store 都只是一个 json 文件,因此在启动时应用程序会扫描文件夹并为每个 json 文件创建一个 Store 对象。但我不知道这是否是一个好的解决方案。这是我第一次使用 Spring Boot。感谢您的帮助!

【问题讨论】:

  • 我从未尝试过使用 ConfigurationProperties 的地图,但我认为您可以获取对象列表(商店名称、用户名、密码、主机等),然后将其转换为地图。看看这篇文章 - stackoverflow.com/questions/51378768/….

标签: java spring spring-boot kotlin


【解决方案1】:

this 会有帮助吗?这是在 ConfigurationProperties 类中使用索引列表。

@ConfigurationProperties("system.connection")
// use a fitting name here
public class Stores {

    // reference your Store type
    private final List<Store> store = new ArrayList<>();

    public List<Store> getStore() {
        return this.store;
    }

}
system.connection.store[0].username=foo
system.connection.store[0].password=pass1
...
system.connection.store[1].username=bar
system.connection.store[1].password=pass2

上面的链接中还给出了一个带有地图的示例,但带有索引的列表方法可能更适合您的需求。

【讨论】:

  • 我已经尝试过列表方法,但我收到绑定到目标 [Bindable@210308d5 type = java.util.List, value = 'provided ', annotations = array[[empty]]] 失败:
  • 原因:元素 [system.stores[0].hostname, system.stores[0].name,system.stores[0].password,system.stores[0].port,system .stores[0].username] 未绑定。
  • 好的,它是在我删除 @Configuration 并且只保留 @ConfigurationProperties("system") 时构建的
  • 但是大小还是0....
  • 您的 application.properties 文件是否正确加载?您能否检查 application.properties 中的其他属性是否存在?例如。在上面的 Store 类中添加一个简单的 String 字段并检查是否至少分配了这个,如果没有,问题就开始了。
【解决方案2】:

通过玩一点,我设法解决了这个问题。我将我的课程恢复为 Kotlin,并对检索值的方式进行了一些调整。这是在 Spring Boot 中使用 Kotlin 从 application.properties 加载动态对象的方式:

假设您有一个名为 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,
)

在您的 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

这在您的 StoresConfiguration.kt 中

@Configuration
@ConfigurationProperties(prefix = "system")
class StoreConfiguration(
    var stores: HashMap<String, Store> = HashMap()
) {

    fun getStore(storeName: String) : Store? {
        return stores.get(storeName)
    }


}

然后假设您想要获取对象并在您的服务类之一中使用它们:

@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

}

}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-04
    • 2020-09-07
    • 1970-01-01
    • 2018-07-20
    • 2017-06-18
    • 2017-01-26
    • 2015-01-03
    • 1970-01-01
    相关资源
    最近更新 更多