首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在vert.x中,为什么静态方法在静态代码块之前运行?

在vert.x中,为什么静态方法在静态代码块之前运行?
EN

Stack Overflow用户
提问于 2018-08-24 07:31:21
回答 1查看 322关注 0票数 2

我有一个类ConfigFactory,它可以通过vert.xconf模块从JSON文件中给出一些配置。

代码语言:javascript
复制
public class ConfigFactory {
    private static JsonObject result = new JsonObject();
    static {
        ConfigStoreOptions fileStore = new ConfigStoreOptions()
                .setType("file")
                .setOptional(true)
                .setFormat("json")
                .setConfig(new JsonObject().put("path", "conf/config.json"));
        ConfigRetrieverOptions options = new ConfigRetrieverOptions().addStore(fileStore);
        ConfigRetriever retriever = ConfigRetriever.create(VertxSingleton.VERTX, options);
        retriever.getConfig(ar -> {
            if (ar.failed()) {
                throw new RuntimeException("Config get error! Something went wring during getting the config");
            } else {
                result.mergeIn(ar.result());
            }
        });
    }

    public static JsonObject getHttpConfig() {
        BiFunction<Integer, String, JsonObject> httpConfigFile = (port, host) -> new JsonObject()
                .put("port", port).put("host", host);
        if (!result.isEmpty()) {
            JsonObject http = result.getJsonObject("http");
            return httpConfigFile.apply(http.getInteger("port"), http.getString("host"));
        } else {
            throw new RuntimeException("HTTP Config get error! Something went wring during getting the config");
        }

    }
}

但是在垂直,我使用JsonObject httpConfig = ConfigFactory.getHttpConfig();,它会给我例外HTTP Config get error! Something went wring during getting the config.In这次,result是空的。

我发现静态方法getHttpConfig在静态代码块之前运行。大约一秒,静态代码块将运行。当时,result并不是空的。

你能帮帮我吗?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-24 08:10:58

与其说是vertX相关的问题,不如说是一个设计问题。静态块是在类加载器加载类时执行的,这基本上是在首次引用类时发生的。如果您第一次引用是在使用ConfigFactory.getHttpConfig();时,那么类加载器将加载该类,则执行静态块,并使用处理程序调用retrieveConfig。不幸的是,它没有阻塞执行(处理程序等待结果),您可以立即调用类。因此,为了使其正常工作,您应该在getHttpConfig()完成初始化之后调用它。

  • 将使静态块同步的解决方案是使用未来选项。

例如:

代码语言:javascript
复制
Future<JsonObject> futureJson=ConfigRetriever.getConfigAsFuture(retriever);
JsonObject obj=futureJson.get();

在静态块中调用future.get()时,它将等到获取配置后再继续。这似乎是一个更容易理解的解决方案,但我不会使用它。它是异步的,是有原因的,我们不应该改变这种行为。

  • 另一个可能需要更多编码的解决方案是添加一个静态字段,显示它是否处于工作状态。

例如:

代码语言:javascript
复制
private static JsonObject result = new JsonObject();
private static boolean readyToGo;
    static {       
        retriever.getConfig(ar -> {
           ....
            if (ar.failed()) {
             ...
            } else {
                result.mergeIn(ar.result());
                ConfigFactory.readyToGo=true; //Now we are good to go
            }
        });
    }

然后

代码语言:javascript
复制
   public static JsonObject getHttpConfig() {
      if (!readyToGo) throw Exception
    }

添加一个isReady()方法,当您调用getHttpConfig()方法时,首先调用isReady()。类似于:

代码语言:javascript
复制
while(!ConfigFactory.isReady()){
//wait ;)
}
ConfigFactory.getHttpConfig(); //it will work here

我想您可以更好地编写它;)但是一般的想法是,如果对象准备使用或不使用,则保持状态。执行静态配置并不能保证对象处于就绪状态,因此您应该自己管理该状态。

  • 简单的解决方案是在启动时调用类一次,这样它就可以初始化(类加载),然后调用getHttpConfig()。它不能保证100%的结果,但如果检索花费太多的时间,或者即使它从来没有完成检索配置。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51999544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档