异地加载 Spring Boot 配置文件

1 异地加载 Spring Boot 配置文件

平时,项目的yaml格式或者properties格式的配置信息文件都固化在了项目jar包里面,不便于动态更改。之前我写过一小段时间的Go,我都是从Redis里读取了相关的配置之后,再完成项目的启动。于是乎,我想在Spring Boot里也捣鼓一下。

要完成配置文件的替换,那么必须在Spring Boot启动之前完成,也就是说像这样子

@SpringBootApplicationclass Applicationfun main(args: Array<String>) {  // 加载配置文件,然后再运行↓将Spring Boot跑起来  runApplication<Application>(*args)}

实现

思路有了之后就简单了,一波操作​​​​​​​

val logger = LoggerFactory.getLogger(RedisConfigLoader::class.java)
val classLoader = RedisConfigLoader::class.java.classLoaderval 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!")

在Idea里运行没问题,跑起来了,但是,当打包成jar包之后就行不通了,会爆异常​​​​​​​

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

解决办法也很简单,把jar包解压出来跑😂,实际上也不会很麻烦,解压在CI构建阶段完成即可。不过要完成项目的启动,必须先找到Spring Boot的启动类。打开jar包,查看里面的META-INF/MENIFEST.MF文件,可以看到Main-Class是org.springframework.boot.loader.JarLauncher

 

 

那么我们的启动命令将改成这样就大功告成

java -cp /解压出来的文件夹根目录 org.springframework.boot.loader.JarLauncher redis 127.0.0.1 6379 redis_password app_config_key

重构

最后稍微重构一下代码 定义一个配置加载器接口​​​​​​​

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

简单写个工厂​​​​​​​

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

实现一个RedisConfigLoader,把之前的代码拷贝的load方法里,稍微改一下即可,完整代码点这里:

https://gist.github.com/Nomyfan/5ec0d8f13b6f8e6faff1d14ac212377e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值