如何異地加載 Spring Boot 配置文件?


如何異地加載 Spring Boot 配置文件?


要完成配置文件的替換,那麼必須在Spring Boot啟動之前完成,也就是說像這樣子

<code>@SpringBootApplication
class Application
fun main(args: Array<string>) {
// 加載配置文件,然後再運行↓將Spring Boot跑起來
runApplication<application>(*args)
}/<application>/<string>/<code>

實現

思路有了之後就簡單了,一波操作

<code>val logger = LoggerFactory.getLogger(RedisConfigLoader::class.java)

val classLoader = RedisConfigLoader::class.java.classLoader
val url = classLoader.getResource("application.yaml")
?: throw ConfigLoadingException("Cannot find the resource") // 自定義的異常
val path = Paths.get(url.toURI())
logger.info("Resource file path is $path")
val channel = FileOutputStream(path.toFile()).channel

val host = args[0]
val port = args[1].toInt()
val password = args[2].toCharArray()
val key = args[3]

val redisURI = RedisURI(host, port, Duration.ofSeconds(5)).apply { this.password = password }
val redisClient = RedisClient.create(redisURI)
val conn = redisClient.connect()
logger.info("Connected to Redis")

val value = conn.sync().get(key)
if (value.isNullOrEmpty()) {
throw ConfigLoadingException("Cannot read resource from redis with key named $key")
}

val buffer = ByteBuffer.wrap(value.toByteArray())
channel.write(buffer)

channel.close()
conn.close()
redisClient.shutdown()
logger.info("Replaced the resource file successfully!")/<code>

在Idea裡運行沒問題,跑起來了,但是,當打包成jar包之後就行不通了,會爆異常

<code>Caused by: java.nio.file.FileSystemNotFoundException
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:166)/<code>

解決辦法也很簡單,把jar包解壓出來跑,實際上也不會很麻煩,解壓在CI構建階段完成即可。不過要完成項目的啟動,必須先找到Spring Boot的啟動類。打開jar包,查看裡面的META-INF/MENIFEST.MF文件,可以看到Main-Class是org.springframework.boot.loader.JarLauncher

如何異地加載 Spring Boot 配置文件?

那麼我們的啟動命令將改成這樣就大功告成

<code>java -cp /解壓出來的文件夾根目錄 org.springframework.boot.loader.JarLauncher redis 127.0.0.1 6379 redis_password app_config_key/<code>

重構

最後稍微重構一下代碼 定義一個配置加載器接口

<code>interface ConfigLoader {
@Throws(ConfigLoadingException::class) // 自定義異常
fun load(resourceName: String, args: Array<string>)
}/<string>/<code>

簡單寫個工廠

<code>class ConfigLoaderFactory {
companion object {
fun loaderOf(type: String): ConfigLoader {
return when (type) {
"redis" -> RedisConfigLoader()
else -> throw ConfigLoaderNotFoundException("Cannot find the config loader typed $type") // 自定義異常
}
}
}
}/<code>


分享到:


相關文章: