Vertx实现和spring的application.yml自动配置加载
前言
在用vertx写项目的时候,由于需要不同的环境加载不同的配置文件,这里就需要和spring架构的application.yml配置文件一样,可以根据环境变量加载不同的配置。
代码
引入vertx相关依赖
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-yaml</artifactId>
<version>4.4.6</version>
</dependency>
编写配置文件
server:
port: 8080
redis:
endpoint: redis://127.0.0.1:6379/2
password: 123456
这里可以编写多个配置文件,在设置不同的环境变量决定需要加载哪个配置文件
实现vertical
加载配置文件中的配置,这里环境变量的参数覆盖配置文件中的变量,这样改变量的时候无需更改代码。
import com.client.config.Constants;
import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.*;
import io.vertx.core.json.JsonObject;
import io.vertx.redis.client.Redis;
import io.vertx.redis.client.RedisAPI;
import io.vertx.redis.client.RedisOptions;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.net.InetAddress;
import java.util.Arrays;
/**
* @author yan
* @since 2024-01-22
*/
@Slf4j
public class MainVerticle extends AbstractVerticle {
@Override
public void start(Promise<Void> startPromise) throws Exception {
ConfigRetrieverOptions options = new ConfigRetrieverOptions();
options.setScanPeriod(0);
options.addStore(new ConfigStoreOptions().setType("sys"));
options.addStore(new ConfigStoreOptions().setType("env"));
ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
retriever.getConfig().flatMap(config -> {
// 加载配置文件
ConfigRetrieverOptions appOptions = new ConfigRetrieverOptions();
appOptions.setScanPeriod(0);
ConfigStoreOptions storeOptions = new ConfigStoreOptions();
storeOptions.setType("file").setFormat("yaml").setConfig(new JsonObject().put("path", "application.yml"));
appOptions.addStore(storeOptions);
String profile = config.getString("profiles_active");
log.info("profiles active:" + profile);
if (StringUtils.isNotEmpty(profile)) {
ConfigStoreOptions profileStoreOptions = new ConfigStoreOptions();
profileStoreOptions.setType("file").setFormat("yaml").setConfig(new JsonObject().put("path", "application-" + profile + ".yml"));
appOptions.addStore(profileStoreOptions);
}
return ConfigRetriever.create(vertx, appOptions).getConfig().map(appConfig -> appConfig.mergeIn(config));
}).flatMap(config -> {
try {
// 加载环境变量redis
JsonObject redis = config.getJsonObject("redis");
String redisEndpoint = config.getString(Constants.Redis.ENDPOINT);
if(StringUtils.isNotEmpty(redisEndpoint)){
redis.put("endpoint", redisEndpoint);
}
String password = config.getString(Constants.Redis.PASSWORD);
if(StringUtils.isNotEmpty(password)){
redis.put("password", password);
}
config.put("redis", redis);
} catch (Exception e) {
log.error("get config error:", e);
}
return Future.succeededFuture(config);
}).map(config -> {
DeploymentOptions deploymentOptions = new DeploymentOptions();
deploymentOptions.setConfig(config);
deploymentOptions.setInstances(VertxOptions.DEFAULT_EVENT_LOOP_POOL_SIZE);
return vertx.deployVerticle(ClientStater.class, deploymentOptions)
.<Void>mapEmpty()
.onComplete(startPromise);
});
}
}
随后初始化redisApi,方便下面的业务直接调用
/**
* @author yan
* @since 2023-12-25
*/
@Slf4j
public class ClientStater extends AbstractVerticle {
@Override
public void start(Promise<Void> startPromise) throws Exception {
JsonObject config = vertx.getOrCreateContext().config();
// 加载redis配置
RedisOptions redisOptions = new RedisOptions(config.getJsonObject("redis"));
Redis client = Redis.createClient(vertx, redisOptions);
RedisAPI redisAPI = RedisAPI.api(client);
// 这里存储redisAPI,方便其他服务调用
RedisConfig.saveRedisApi(vertx, redisAPI);
// 启动http服务
WebServer webServer = new WebServer(vertx, config.getJsonObject("server").getInteger("port"));
webServer.start().onComplete(startPromise);
}
}
通过以上步骤在下面的服务就能正常使用配置文件中的变量了,可以接着往下封装配置了。