feat(config): 重构配置管理
This commit is contained in:
parent
e97f3f5519
commit
e7016373c2
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,7 +5,8 @@ build/
|
||||
!**/src/test/**/build/
|
||||
/config
|
||||
/gradle
|
||||
log/
|
||||
/logs
|
||||
/.cursor
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
|
||||
@ -1,21 +1,20 @@
|
||||
package app.config
|
||||
|
||||
import app.config.auth.JWTAuthProvider
|
||||
import app.config.db.DbPoolProvider
|
||||
import cn.hutool.core.lang.Snowflake
|
||||
import cn.hutool.core.util.IdUtil
|
||||
import com.google.inject.*
|
||||
import com.google.inject.name.Names
|
||||
import com.google.inject.AbstractModule
|
||||
import com.google.inject.Guice
|
||||
import com.google.inject.Injector
|
||||
import com.google.inject.Singleton
|
||||
import io.vertx.core.Vertx
|
||||
import io.vertx.ext.auth.jwt.JWTAuth
|
||||
import io.vertx.pgclient.PgBuilder
|
||||
import io.vertx.pgclient.PgConnectOptions
|
||||
import io.vertx.sqlclient.Pool
|
||||
import io.vertx.sqlclient.PoolOptions
|
||||
import io.vertx.sqlclient.SqlClient
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import org.aikrai.vertx.config.Config
|
||||
import org.aikrai.vertx.config.DefaultScope
|
||||
import org.aikrai.vertx.db.tx.TxMgrHolder.initTxMgr
|
||||
import org.aikrai.vertx.config.FrameworkConfigModule
|
||||
|
||||
object InjectConfig {
|
||||
fun configure(vertx: Vertx): Injector {
|
||||
@ -27,44 +26,21 @@ class InjectorModule(
|
||||
private val vertx: Vertx,
|
||||
) : AbstractModule() {
|
||||
override fun configure() {
|
||||
val pool = getDbPool().also { initTxMgr(it) }
|
||||
val coroutineScope = DefaultScope(vertx)
|
||||
// 1. 安装框架提供的配置模块
|
||||
install(FrameworkConfigModule())
|
||||
|
||||
for ((key, value) in Config.getConfigMap()) {
|
||||
bind(String::class.java).annotatedWith(Names.named(key)).toInstance(value.toString())
|
||||
}
|
||||
// 2. 绑定 Vertx 实例和 CoroutineScope
|
||||
bind(Vertx::class.java).toInstance(vertx)
|
||||
bind(CoroutineScope::class.java).toInstance(coroutineScope)
|
||||
bind(CoroutineScope::class.java).toInstance(DefaultScope(vertx))
|
||||
|
||||
// 3. 绑定 Snowflake
|
||||
bind(Snowflake::class.java).toInstance(IdUtil.getSnowflake())
|
||||
|
||||
// 4. 绑定数据库连接池 (使用 Provider 来延迟创建)
|
||||
bind(Pool::class.java).toProvider(DbPoolProvider::class.java).`in`(Singleton::class.java)
|
||||
bind(SqlClient::class.java).to(Pool::class.java) // 绑定 SqlClient 到 Pool
|
||||
|
||||
// 5. 绑定 JWTAuth
|
||||
bind(JWTAuth::class.java).toProvider(JWTAuthProvider::class.java).`in`(Singleton::class.java)
|
||||
|
||||
// 绑定 DbPool 为单例
|
||||
bind(Pool::class.java).toInstance(pool)
|
||||
bind(SqlClient::class.java).toInstance(pool)
|
||||
}
|
||||
|
||||
private fun getDbPool(): Pool {
|
||||
// val type = configMap["databases.type"].toString()
|
||||
// val name = configMap["databases.name"].toString()
|
||||
// val host = configMap["databases.host"].toString()
|
||||
// val port = configMap["databases.port"].toString()
|
||||
// val user = configMap["databases.username"].toString()
|
||||
// val password = configMap["databases.password"].toString()
|
||||
// val dbMap = Config.getKey("databases") as Map<String, String>
|
||||
val name = Config.getKey("databases.name").toString()
|
||||
val host = Config.getKey("databases.host").toString()
|
||||
val port = Config.getKey("databases.port").toString()
|
||||
val user = Config.getKey("databases.username").toString()
|
||||
val password = Config.getKey("databases.password").toString()
|
||||
|
||||
val poolOptions = PoolOptions().setMaxSize(10)
|
||||
val clientOptions = PgConnectOptions()
|
||||
.setHost(host)
|
||||
.setPort(port.toInt())
|
||||
.setDatabase(name)
|
||||
.setUser(user)
|
||||
.setPassword(password)
|
||||
.setTcpKeepAlive(true)
|
||||
return PgBuilder.pool().connectingTo(clientOptions).with(poolOptions).using(vertx).build()
|
||||
}
|
||||
}
|
||||
@ -2,22 +2,22 @@ package app.config.auth
|
||||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Provider
|
||||
import com.google.inject.name.Named
|
||||
import io.vertx.core.Vertx
|
||||
import io.vertx.ext.auth.PubSecKeyOptions
|
||||
import io.vertx.ext.auth.jwt.JWTAuth
|
||||
import io.vertx.ext.auth.jwt.JWTAuthOptions
|
||||
import org.aikrai.vertx.config.JwtConfig
|
||||
|
||||
class JWTAuthProvider @Inject constructor(
|
||||
private val vertx: Vertx,
|
||||
@Named("jwt.key") private val key: String
|
||||
private val jwtConfig: JwtConfig
|
||||
) : Provider<JWTAuth> {
|
||||
override fun get(): JWTAuth {
|
||||
val options = JWTAuthOptions()
|
||||
.addPubSecKey(
|
||||
PubSecKeyOptions()
|
||||
.setAlgorithm("HS256")
|
||||
.setBuffer(key)
|
||||
.setAlgorithm(jwtConfig.algorithm)
|
||||
.setBuffer(jwtConfig.key)
|
||||
)
|
||||
return JWTAuth.create(vertx, options)
|
||||
}
|
||||
|
||||
43
vertx-demo/src/main/kotlin/app/config/db/DbPoolProvider.kt
Normal file
43
vertx-demo/src/main/kotlin/app/config/db/DbPoolProvider.kt
Normal file
@ -0,0 +1,43 @@
|
||||
package app.config.db
|
||||
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Provider
|
||||
import com.google.inject.Singleton
|
||||
import io.vertx.core.Vertx
|
||||
import io.vertx.pgclient.PgBuilder
|
||||
import io.vertx.pgclient.PgConnectOptions
|
||||
import io.vertx.sqlclient.Pool
|
||||
import io.vertx.sqlclient.PoolOptions
|
||||
import org.aikrai.vertx.config.DatabaseConfig
|
||||
import org.aikrai.vertx.db.tx.TxMgrHolder
|
||||
|
||||
/**
|
||||
* 数据库连接池提供者
|
||||
*/
|
||||
@Singleton
|
||||
class DbPoolProvider @Inject constructor(
|
||||
private val vertx: Vertx,
|
||||
private val dbConfig: DatabaseConfig
|
||||
) : Provider<Pool> {
|
||||
override fun get(): Pool {
|
||||
val poolOptions = PoolOptions().setMaxSize(dbConfig.maxPoolSize)
|
||||
val clientOptions = PgConnectOptions()
|
||||
.setHost(dbConfig.host)
|
||||
.setPort(dbConfig.port)
|
||||
.setDatabase(dbConfig.name)
|
||||
.setUser(dbConfig.username)
|
||||
.setPassword(dbConfig.password)
|
||||
.setTcpKeepAlive(true)
|
||||
|
||||
val pool = PgBuilder.pool()
|
||||
.connectingTo(clientOptions)
|
||||
.with(poolOptions)
|
||||
.using(vertx)
|
||||
.build()
|
||||
|
||||
// 初始化事务管理器
|
||||
TxMgrHolder.initTxMgr(pool)
|
||||
|
||||
return pool
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ class Demo1Controller @Inject constructor(
|
||||
suspend fun testRetriever(
|
||||
@D("key", "key") key: String
|
||||
) {
|
||||
val configMap = Config.getKey(key)
|
||||
val configMap = Config.getStringOrNull(key)
|
||||
println(configMap)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,24 +2,25 @@ package app.port.aipfox
|
||||
|
||||
import app.util.openapi.OpenApiSpecGenerator
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.name.Named
|
||||
import io.vertx.core.Vertx
|
||||
import io.vertx.core.http.HttpMethod
|
||||
import io.vertx.core.json.JsonObject
|
||||
import io.vertx.ext.web.client.WebClient
|
||||
import io.vertx.ext.web.client.WebClientOptions
|
||||
import mu.KotlinLogging
|
||||
import org.aikrai.vertx.config.Config
|
||||
|
||||
class ApifoxClient @Inject constructor(
|
||||
private val vertx: Vertx,
|
||||
@Named("apifox.token") private val token: String,
|
||||
@Named("apifox.projectId") private val projectId: String,
|
||||
@Named("apifox.folderId") private val folderId: String,
|
||||
@Named("server.name") private val serverName: String,
|
||||
@Named("server.port") private val port: String
|
||||
) {
|
||||
private val logger = KotlinLogging.logger { }
|
||||
|
||||
private val token = Config.getString("apifox.token", "")
|
||||
private val projectId = Config.getString("apifox.projectId", "")
|
||||
private val folderId = Config.getString("apifox.folderId", "")
|
||||
private val serverName = Config.getString("server.name", "")
|
||||
private val port = Config.getString("server.port", "")
|
||||
|
||||
fun importOpenapi() {
|
||||
val openApiJsonStr = OpenApiSpecGenerator().genOpenApiSpecStr(serverName, "1.0", "http://127.0.0.1:$port/api")
|
||||
val options = WebClientOptions().setDefaultPort(443).setDefaultHost("api.apifox.com").setSsl(true)
|
||||
|
||||
@ -6,28 +6,23 @@ import io.vertx.core.Vertx
|
||||
import io.vertx.kotlin.coroutines.coAwait
|
||||
import io.vertx.redis.client.*
|
||||
import mu.KotlinLogging
|
||||
import org.aikrai.vertx.config.Config
|
||||
import org.aikrai.vertx.config.RedisConfig
|
||||
|
||||
@Singleton
|
||||
class RedisClient @Inject constructor(
|
||||
vertx: Vertx
|
||||
vertx: Vertx,
|
||||
redisConfig: RedisConfig
|
||||
) {
|
||||
private val logger = KotlinLogging.logger { }
|
||||
private val host = Config.getKey("redis.host").toString()
|
||||
private val port = Config.getKey("redis.port").toString()
|
||||
private val database = Config.getKey("redis.database").toString().toInt()
|
||||
private val password = Config.getKey("redis.password").toString()
|
||||
private val maxPoolSize = Config.getKey("redis.maxPoolSize").toString().toInt()
|
||||
private val maxPoolWaiting = Config.getKey("redis.maxPoolWaiting").toString().toInt()
|
||||
|
||||
private var redisClient = Redis.createClient(
|
||||
vertx,
|
||||
RedisOptions()
|
||||
.setType(RedisClientType.STANDALONE)
|
||||
.addConnectionString("redis://$host:$port/$database")
|
||||
.setPassword(password)
|
||||
.setMaxPoolSize(maxPoolSize)
|
||||
.setMaxPoolWaiting(maxPoolWaiting)
|
||||
.addConnectionString("redis://${redisConfig.host}:${redisConfig.port}/${redisConfig.db}")
|
||||
.setPassword(redisConfig.pass ?: "")
|
||||
.setMaxPoolSize(redisConfig.poolSize)
|
||||
.setMaxPoolWaiting(redisConfig.maxPoolWaiting)
|
||||
)
|
||||
|
||||
// EX秒,PX毫秒
|
||||
|
||||
@ -9,7 +9,6 @@ import app.port.aipfox.ApifoxClient
|
||||
import cn.hutool.core.lang.Snowflake
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Injector
|
||||
import com.google.inject.name.Named
|
||||
import io.vertx.core.Handler
|
||||
import io.vertx.core.http.HttpHeaders
|
||||
import io.vertx.core.http.HttpMethod
|
||||
@ -23,7 +22,7 @@ import io.vertx.kotlin.coroutines.coAwait
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import mu.KotlinLogging
|
||||
import org.aikrai.vertx.auth.AuthUser
|
||||
import org.aikrai.vertx.config.Config
|
||||
import org.aikrai.vertx.config.ServerConfig
|
||||
import org.aikrai.vertx.context.RouterBuilder
|
||||
import org.aikrai.vertx.jackson.JsonUtil
|
||||
import org.aikrai.vertx.utlis.LangUtil.toStringMap
|
||||
@ -36,8 +35,7 @@ class WebVerticle @Inject constructor(
|
||||
private val apifoxClient: ApifoxClient,
|
||||
private val snowflake: Snowflake,
|
||||
private val responseHandler: ResponseHandler,
|
||||
@Named("server.port") private val port: Int,
|
||||
@Named("server.context") private val context: String,
|
||||
private val serverConfig: ServerConfig
|
||||
) : CoroutineVerticle() {
|
||||
private val logger = KotlinLogging.logger { }
|
||||
|
||||
@ -48,30 +46,29 @@ class WebVerticle @Inject constructor(
|
||||
val options = HttpServerOptions().setMaxFormAttributeSize(1024 * 1024)
|
||||
val server = vertx.createHttpServer(options)
|
||||
.requestHandler(rootRouter)
|
||||
.listen(port)
|
||||
.listen(serverConfig.port)
|
||||
.coAwait()
|
||||
|
||||
apifoxClient.importOpenapi()
|
||||
|
||||
logger.info { "http server start - http://127.0.0.1:${server.actualPort()}/$context" }
|
||||
logger.info { "http server start - http://127.0.0.1:${server.actualPort()}${serverConfig.context}" }
|
||||
}
|
||||
|
||||
override suspend fun stop() {
|
||||
}
|
||||
|
||||
private fun setupRouter(rootRouter: Router, router: Router) {
|
||||
rootRouter.route("/api" + "*").subRouter(router)
|
||||
rootRouter.route("${serverConfig.context}*").subRouter(router)
|
||||
router.route()
|
||||
.handler(corsHandler)
|
||||
.handler(BodyHandler.create())
|
||||
.handler(logHandler)
|
||||
.failureHandler(errorHandler)
|
||||
|
||||
val authHandler = JwtAuthenticationHandler(coroutineScope, tokenService, context, snowflake)
|
||||
val authHandler = JwtAuthenticationHandler(coroutineScope, tokenService, serverConfig.context, snowflake)
|
||||
router.route("/*").handler(authHandler)
|
||||
|
||||
val scanPath = Config.getKeyAsString("server.package")
|
||||
val routerBuilder = RouterBuilder(coroutineScope, router, scanPath, responseHandler).build { service ->
|
||||
val routerBuilder = RouterBuilder(coroutineScope, router, serverConfig.scanPackage, responseHandler).build { service ->
|
||||
getIt.getInstance(service)
|
||||
}
|
||||
authHandler.anonymous.addAll(routerBuilder.anonymousPaths)
|
||||
|
||||
@ -1,15 +1,5 @@
|
||||
server:
|
||||
name: vtx_demo
|
||||
context: api # 上下文
|
||||
timeout: 120 # eventbus超时时间
|
||||
http:
|
||||
header: # header获取到的变量
|
||||
- x-requested-with
|
||||
- Access-Control-Allow-Origin
|
||||
- origin
|
||||
- Content-Type
|
||||
- accept
|
||||
event-bus:
|
||||
timeout: 10000 # 毫秒
|
||||
jwt:
|
||||
key: 123456sdfjasdfjl # jwt加密key
|
||||
context: /api
|
||||
# active: dev
|
||||
package: app
|
||||
18
vertx-demo/src/main/resources/config/application.yaml
Normal file
18
vertx-demo/src/main/resources/config/application.yaml
Normal file
@ -0,0 +1,18 @@
|
||||
application:
|
||||
version: 1.0.0
|
||||
|
||||
server:
|
||||
http:
|
||||
header: # header获取到的变量
|
||||
- x-requested-with
|
||||
- Access-Control-Allow-Origin
|
||||
- origin
|
||||
- Content-Type
|
||||
- accept
|
||||
event-bus:
|
||||
timeout: 10000 # 毫秒
|
||||
|
||||
jwt:
|
||||
key: 123456sdfjasdfjl
|
||||
algorithm: HS256
|
||||
expiresInSeconds: 604800 # 7天
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration
|
||||
debug="false" scan="true" scanPeriod="30 second">
|
||||
<property name="ROOT" value="./log/"/>
|
||||
<property name="ROOT" value="./logs/"/>
|
||||
<property name="APPNAME" value="vertx-demo"/>
|
||||
<property name="FILESIZE" value="500MB"/>
|
||||
<property name="MAXHISTORY" value="100"/>
|
||||
|
||||
@ -3,7 +3,6 @@ package app
|
||||
import org.aikrai.vertx.db.annotation.TableField
|
||||
import org.aikrai.vertx.db.annotation.TableId
|
||||
import org.aikrai.vertx.db.annotation.TableName
|
||||
import org.aikrai.vertx.db.annotation.TableIndex
|
||||
import org.aikrai.vertx.db.annotation.EnumValue
|
||||
import org.aikrai.vertx.db.annotation.TableFieldComment
|
||||
import org.aikrai.vertx.db.migration.AnnotationMapping
|
||||
@ -98,10 +97,10 @@ object GenerateMigration {
|
||||
)
|
||||
|
||||
// 设置索引映射
|
||||
mapper.indexMapping = AnnotationMapping(
|
||||
annotationClass = TableIndex::class,
|
||||
propertyName = "name"
|
||||
)
|
||||
// mapper.indexMapping = AnnotationMapping(
|
||||
// annotationClass = TableIndex::class,
|
||||
// propertyName = "name"
|
||||
// )
|
||||
|
||||
// 设置枚举值映射
|
||||
mapper.enumValueMapping = AnnotationMapping(
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
package org.aikrai.vertx.config
|
||||
|
||||
/**
|
||||
* 数据库配置
|
||||
*/
|
||||
data class DatabaseConfig(
|
||||
val name: String,
|
||||
val host: String,
|
||||
val port: Int,
|
||||
val username: String,
|
||||
val password: String,
|
||||
val maxPoolSize: Int = 10
|
||||
)
|
||||
|
||||
/**
|
||||
* Redis配置
|
||||
*/
|
||||
data class RedisConfig(
|
||||
val host: String,
|
||||
val port: Int,
|
||||
val db: Int,
|
||||
val pass: String?,
|
||||
val poolSize: Int = 8,
|
||||
val maxPoolWaiting: Int = 32
|
||||
)
|
||||
|
||||
/**
|
||||
* JWT配置
|
||||
*/
|
||||
data class JwtConfig(
|
||||
val key: String,
|
||||
val algorithm: String = "HS256",
|
||||
val expiresInSeconds: Int = 60 * 60 * 24 * 7 // 7天
|
||||
)
|
||||
|
||||
/**
|
||||
* 服务器配置
|
||||
*/
|
||||
data class ServerConfig(
|
||||
val port: Int,
|
||||
val context: String,
|
||||
val scanPackage: String
|
||||
)
|
||||
|
||||
/**
|
||||
* 框架配置
|
||||
*/
|
||||
data class FrameworkConfiguration(
|
||||
val server: ServerConfig,
|
||||
val database: DatabaseConfig,
|
||||
val redis: RedisConfig,
|
||||
val jwt: JwtConfig
|
||||
)
|
||||
@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
object Config {
|
||||
private val retriever = AtomicReference<ConfigRetriever?>(null)
|
||||
private var configMap = emptyMap<String, Any>()
|
||||
private val configMapRef = AtomicReference<Map<String, Any>>(emptyMap())
|
||||
|
||||
suspend fun init(vertx: Vertx) {
|
||||
if (retriever.get() != null) return
|
||||
@ -20,38 +20,71 @@ object Config {
|
||||
val cas = retriever.compareAndSet(null, configRetriever)
|
||||
if (cas) {
|
||||
val configObj = configRetriever.config.coAwait()
|
||||
configMap = FlattenUtil.flattenJsonObject(configObj)
|
||||
// 存储扁平化的 Map
|
||||
configMapRef.set(FlattenUtil.flattenJsonObject(configObj))
|
||||
}
|
||||
}
|
||||
|
||||
fun getKey(key: String): Any? {
|
||||
if (retriever.get() == null) throw IllegalStateException("Config not initialized")
|
||||
// 检查 configMap 中是否存在指定的 key
|
||||
return if (configMap.containsKey(key)) {
|
||||
configMap[key]
|
||||
} else {
|
||||
// 找到所有以 key 开头的条目
|
||||
val map = configMap.filterKeys { it.startsWith(key) }
|
||||
// 如果没有找到任何匹配的条目,返回 null
|
||||
return map.ifEmpty { null }
|
||||
fun getString(key: String, defaultValue: String): String {
|
||||
return configMapRef.get()[key]?.toString() ?: defaultValue
|
||||
}
|
||||
|
||||
fun getStringOrNull(key: String): String? {
|
||||
return configMapRef.get()[key]?.toString()
|
||||
}
|
||||
|
||||
fun getInt(key: String, defaultValue: Int): Int {
|
||||
return configMapRef.get()[key]?.toString()?.toIntOrNull() ?: defaultValue
|
||||
}
|
||||
|
||||
fun getIntOrNull(key: String): Int? {
|
||||
return configMapRef.get()[key]?.toString()?.toIntOrNull()
|
||||
}
|
||||
|
||||
fun getLong(key: String, defaultValue: Long): Long {
|
||||
return configMapRef.get()[key]?.toString()?.toLongOrNull() ?: defaultValue
|
||||
}
|
||||
|
||||
fun getLongOrNull(key: String): Long? {
|
||||
return configMapRef.get()[key]?.toString()?.toLongOrNull()
|
||||
}
|
||||
|
||||
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
|
||||
val value = configMapRef.get()[key]
|
||||
return when (value) {
|
||||
is Boolean -> value
|
||||
is String -> value.toBooleanStrictOrNull() ?: defaultValue // toBooleanStrictOrNull 更安全
|
||||
else -> defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
fun getKeyAsString(key: String): String? {
|
||||
if (retriever.get() == null) throw IllegalStateException("Config not initialized")
|
||||
// 检查 configMap 中是否存在指定的 key
|
||||
return if (configMap.containsKey(key)) {
|
||||
configMap[key].toString()
|
||||
} else {
|
||||
// 找到所有以 key 开头的条目
|
||||
val map = configMap.filterKeys { it.startsWith(key) }
|
||||
// 如果没有找到任何匹配的条目,返回 null
|
||||
if (map.isEmpty()) return null else map.toString()
|
||||
fun getBooleanOrNull(key: String): Boolean? {
|
||||
val value = configMapRef.get()[key]
|
||||
return when (value) {
|
||||
is Boolean -> value
|
||||
is String -> value.toBooleanStrictOrNull()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
// 获取嵌套对象或列表
|
||||
fun getObject(keyPrefix: String): Map<String, Any>? {
|
||||
val map = configMapRef.get()
|
||||
val subMap = map.filterKeys { it.startsWith("$keyPrefix.") }
|
||||
.mapKeys { it.key.removePrefix("$keyPrefix.") }
|
||||
return if (subMap.isEmpty()) null else subMap
|
||||
}
|
||||
|
||||
fun getStringList(key: String, defaultValue: List<String> = emptyList()): List<String> {
|
||||
return (configMapRef.get()[key] as? JsonArray)?.mapNotNull { it?.toString() } ?: defaultValue
|
||||
}
|
||||
|
||||
fun getStringListOrNull(key: String): List<String>? {
|
||||
return (configMapRef.get()[key] as? JsonArray)?.mapNotNull { it?.toString() }
|
||||
}
|
||||
|
||||
fun getConfigMap(): Map<String, Any> {
|
||||
return configMap
|
||||
return configMapRef.get()
|
||||
}
|
||||
|
||||
private suspend fun load(vertx: Vertx): ConfigRetriever {
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
package org.aikrai.vertx.config
|
||||
|
||||
import com.google.inject.AbstractModule
|
||||
import com.google.inject.Provides
|
||||
import com.google.inject.Singleton
|
||||
|
||||
/**
|
||||
* 框架配置模块
|
||||
*
|
||||
* 负责使用增强后的Config对象读取配置,并将其实例化为数据类进行绑定
|
||||
*/
|
||||
class FrameworkConfigModule : AbstractModule() {
|
||||
|
||||
override fun configure() {
|
||||
// 这里不需要bind(Config::class.java),因为Config是object
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideDatabaseConfig(): DatabaseConfig {
|
||||
return DatabaseConfig(
|
||||
name = Config.getString("databases.name", "default_db"),
|
||||
host = Config.getString("databases.host", "localhost"),
|
||||
port = Config.getInt("databases.port", 5432),
|
||||
username = Config.getString("databases.username", "user"),
|
||||
password = Config.getString("databases.password", "password"),
|
||||
maxPoolSize = Config.getInt("databases.maxPoolSize", 10)
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideRedisConfig(): RedisConfig {
|
||||
return RedisConfig(
|
||||
host = Config.getString("redis.host", "localhost"),
|
||||
port = Config.getInt("redis.port", 6379),
|
||||
db = Config.getInt("redis.database", 0),
|
||||
pass = Config.getStringOrNull("redis.password"),
|
||||
poolSize = Config.getInt("redis.maxPoolSize", 8),
|
||||
maxPoolWaiting = Config.getInt("redis.maxPoolWaiting", 32)
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideJwtConfig(): JwtConfig {
|
||||
val key = Config.getStringOrNull("jwt.key")
|
||||
?: throw IllegalStateException("缺少必要配置: jwt.key")
|
||||
return JwtConfig(
|
||||
key = key,
|
||||
algorithm = Config.getString("jwt.algorithm", "HS256"),
|
||||
expiresInSeconds = Config.getInt("jwt.expiresInSeconds", 60 * 60 * 24 * 7)
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideServerConfig(): ServerConfig {
|
||||
val scanPackage = Config.getStringOrNull("server.package")
|
||||
?: throw IllegalStateException("缺少必要配置: server.package")
|
||||
return ServerConfig(
|
||||
port = Config.getInt("server.port", 8080),
|
||||
context = Config.getString("server.context", "/api"),
|
||||
scanPackage = scanPackage
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFrameworkConfiguration(
|
||||
server: ServerConfig,
|
||||
database: DatabaseConfig,
|
||||
redis: RedisConfig,
|
||||
jwt: JwtConfig
|
||||
): FrameworkConfiguration {
|
||||
return FrameworkConfiguration(server, database, redis, jwt)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user