【问题标题】:Purpose and behaviour of init() in Vertx classVertx 类中 init() 的目的和行为
【发布时间】:2019-02-07 14:48:10
【问题描述】:

我有以下 Verticle 用于测试目的:

public class UserVerticle extends AbstractVerticle {

  private static final Logger log = LoggerFactory.getLogger(UserVerticle.class);

  @Override
  public void start(Future<Void> sf) {
    log.info("start()");
    JsonObject cnf = config();
    log.info("start.config={}", cnf.toString());
    sf.complete();
  }

  @Override
  public void stop(Future<Void> sf) {
    log.info("stop()");
    sf.complete();
  }

  private void onMessage(Message<JsonObject> message) { ... }
    log.info("onMessage(message={})", message);
  }

}

是从主verticle部署的

  vertx.deployVerticle("org.buguigny.cluster.UserVerticle",
                 new DeploymentOptions()
                 .setInstances(1)
                 .setConfig(new JsonObject()
                        .put(some_key, some_data)
                        ),
                 ar -> {
                   if(ar.succeeded()) {
                     log.info("UserVerticle(uname={}, addr={}) deployed", uname, addr);
                     // continue when OK
                   }
                   else {
                     log.error("Could not deploy UserVerticle(uname={}). Cause: {}", uname, ar.cause());
                     // continue when KO
                   }
                 });

此代码运行良好。

我查看了Verticle 文档并发现了一个我以前没有见过的init() 回调方法。由于文档没有详细说明它的实际作用,我对其进行了定义,以查看它在 Verticle 的生命周期中的哪个位置被调用。

  @Override
  public void init(Vertx vertx, Context context) {
    log.info("init()");
    JsonObject cnf = context.config();
    log.info("init.config={}", cnf.toString());
  }

但是,当init() 被定义时,我在start() 中调用JsonObject cnf = config(); 的行上得到一个java.lang.NullPointerException

java.lang.NullPointerException: null
    at io.vertx.core.AbstractVerticle.config(AbstractVerticle.java:85)
    at org.buguigny.cluster.UserVerticle.start(UserVerticle.java:30)
    at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:494)
    at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
    at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:462)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:748)

我的问题是:

Q1:任何线索为什么会抛出NullPointerException

Q2init()的目的是什么?它是 Vertx 内部的还是可以由客户端代码实现,例如,在部署配置中传递的 Verticle 对象中定义一些字段?

【问题讨论】:

    标签: vert.x vertx-verticle


    【解决方案1】:

    init 方法供内部使用,并记录在 Javadoc 中。这是源代码:

      /**
       * Initialise the verticle.<p>
       * This is called by Vert.x when the verticle instance is deployed. Don't call it yourself.
       * @param vertx  the deploying Vert.x instance
       * @param context  the context of the verticle
       */
      @Override
      public void init(Vertx vertx, Context context) {
        this.vertx = vertx;
        this.context = context;
      }
    

    如果init 记录在任何用户文档中,这是一个错误,请报告。

    【讨论】:

    • 好的,那就清楚了。 init() doc 在 javadocs 中,与start() 的文本几乎相同: 启动verticle 实例。 Vert.x 在部署实例时调用此方法。你自己不叫它。 因此我很困惑。谢谢。
    猜你喜欢
    • 2018-03-27
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    • 2020-02-16
    相关资源
    最近更新 更多