当前位置: 首页 > 知识库问答 >
问题:

在verticle vert.x中实例化类的危险

杜霍英
2023-03-14

我解释了我的问题,我有一个顶点,我定义了所有的路线。我有简单的java类,其中包含我根据路由在顶点中调用的方法。例如,我的下载文件()方法在 MyFile 类中,如下所示:

    public class MyFile {

        public final void downloadFile(RoutingContext rc, Vertx vertx) {
            final HttpServerResponse response = rc.response();
            response.putHeader("Content-Type", "text/html");
            response.setChunked(true);

            rc.fileUploads().forEach(file -> {

                final String fileNameWithoutExtension = file.uploadedFileName();

                final JsonObject jsonObjectWithFileName = new JsonObject();
                 response.setStatusCode(200); 
                 response.end(jsonObjectWithFileName.put("fileName", fileNameWithoutExtension).encodePrettily());
            });
        }

       public final void saveFile(RoutingContext rc, Vertx vertx) {
                 //TODO
       }
    }

我在我的垂直类中这样使用这个类:

    public class MyVerticle extends AbstractVerticle{

            private static final MyFile myFile = new MyFile();

            @Override
            public void start(Future<Void> startFuture) {
                final Router router = Router.router(vertx);
                final EventBus eventBus = vertx.eventBus();

                router.route("/getFile").handler(routingContext -> {
                    myFile.downloadFile(routingContext, vertx);
                });

        router.route("/saveFile").handler(routingContext -> {
                    myFile.saveFile(routingContext, vertx);
                });
            }
    }

我的同事告诉我,在顶点中实例化一个类是不好的,当我问他为什么时,他回答说它变得有状态,我怀疑他对我说的话,因为我不知道该怎么做。当我在顶点中声明 MyFile 类实例为“静态 final”时,我想说我甚至提高了性能,因为我对每个传入请求使用相同的实例,而不是创建一个新实例。

如果在verticle中实例化一个类不好,请解释为什么?

此外,我想知道使用2个顶点进行只有一个顶点才能进行的治疗有什么兴趣?

例如,我想用我在数据库中选择的数据构建一个JsonObject,为什么将此数据发送到另一个顶点,知道这个顶点除了构建JsonObject之外什么都不做,并等待它回答我,将响应发送到客户端,以便我可以在我发出请求的顶点构建此JsonObject,并立即将响应发送到客户端。我给你放一个伪代码,看看更好:

public class MyVerticle1 extends AbstractVerticle{

    public void start(Future<Void> startFuture) {

        connection.query("select * from file", result -> {

            if (result.succeeded()) {
                List<JsonArray> rowsSelected = result.result().getResults();
                eventBus.send("adress", rowsSelected, res -> {
                    if (res.succeded()) {
                        routinContext.response().end(res.result().encodePrettily());
                    }
                });
            } else {
                LOGGER.error(result.cause().toString());
            }

        });

    }

}

public class MyVerticle2 extends AbstractVerticle{

    public void start(Future<Void> startFuture) {
        JsonArray resultOfSelect = new JsonArray();

        eventBus.consumer("adress", message -> {
            List<JsonArray> rowsSelected = (List<JsonArray>) message.body();
            rowsSelected.forEach(jsa -> {
                JsonObject row = new JsonObject();
                row.put("id", jsa.getInteger(0));
                row.put("name", jsa.getString(1));
                resultOfSelect.add(row);
            });

            message.reply(resultOfSelect);
        });
    }
}

我真的看不出制作2个顶点的意义,因为我可以在不使用第二个顶点的情况下在第一个顶点中使用我的查询结果。

共有1个答案

童化
2023-03-14

记住...不幸的是,您正在寻找的答案非常微妙,并且会根据许多条件而变化(例如,回答问题的人的经验、代码库中的设计习惯、您可以使用的工具/库等)。所以没有权威的答案,只有适合你(和你的同事)的答案。

我的同事告诉我,在verticle中实例化一个类是不好的,当我问他为什么时,他回答说它变成了有状态的,我怀疑他对我说的话,因为我不知道怎么做。

您的同事在一般意义上是正确的,您不希望群集中的单个节点保持自己的状态,因为这实际上会妨碍可靠扩展的能力。但是在这种特殊情况下,< code>MyFile看起来是无状态的,因此将其作为Verticle的成员引入并不会自动使服务器成为有状态的。

(如果有什么不同的话,我认为< code>MyFile不仅仅是基于文件的操作,它还处理HTTP请求和响应)。

当我在我的verticle中声明我的MyFile类实例“static final”时,我想说我甚至获得了性能上的提高,因为我对每个传入的请求使用相同的实例,而不是创建一个新的实例。

我会说这与设计偏好有关。这里本身没有任何真正的“伤害”,但我倾向于避免将静态成员用于常量文本以外的任何内容,而是更喜欢使用依赖注入来连接我的依赖关系。但也许这是一个非常简单的项目,引入DI框架超出了您希望引入的复杂性。这完全取决于您的特定情况。

此外,我想知道使用2个顶点进行只有一个顶点才能进行的治疗有什么兴趣?

同样,这取决于您的情况和您的“复杂性预算”。如果处理很简单,并且您希望保持设计同样简单,则单个顶点就可以了(并且可以说更容易理解/概念化和支持)。在较大的应用程序中,我倾向于沿着不同的逻辑域的思路创建许多顶点(例如,用于身份验证的顶点,用于用户帐户功能的顶点等),并通过事件总线编排任何复杂的处理。

 类似资料:
  • 问题内容: 我已经在python中编写了一个类,希望通过IronPython包装到.net程序集中,并在C#应用程序中实例化。我已经将该类迁移到IronPython,创建了一个库程序集并对其进行了引用。现在,我实际上如何获得该类的实例? 该类看起来(部分地)是这样的: 我用C#编写的测试存根是: 为了在C#中实例化此类,我必须做什么? 问题答案: IronPython类 不是.NET类。它们是Ir

  • 问题内容: 我知道Java的泛型在某种程度上逊于.Net。 我有一个泛型类,我确实需要使用无参数构造函数实例化。如何解决Java的局限性? 问题答案: 一种选择是传递(或你感兴趣的任何类型-以任何方式指定适当的引用)并将该值保留为字段: 另一种选择是具有“工厂”接口,然后将工厂传递给泛型类的构造函数。这更加灵活,你无需担心反射异常。

  • 5.4. 类的实例化 5.4.1. 垃圾回收 在 Python 中对类进行实例化很直接。为了对类进行实例化,只要调用类,好象它是一个函数,传入定义在 __init__ 方法中的参数。返回值将是新创建的对象。 例 5.7. 创建 FileInfo 实例 >>> import fileinfo >>> f = fileinfo.FileInfo("/music/_singles/kairo.mp3")

  • Selenium FindBy注释是否实际实例化了WebElement实例,如果是,使用它们的框架的内涵是什么? 我在我的页面对象中所做的事情现在看起来是这样的。我的所有测试框架方法都将定位器作为参数(而不是WebElement实例)。 我的问题是,在类实例化时使用FindBy实例化WebElement实例吗?如果是这样,那么我怀疑我的框架方法需要使用WebElement实例。这是正确的吗,在框架

  • 问题内容: 我想在Java中创建泛型类型的对象。请提出如何实现相同的建议。 注意:这似乎是一个简单的泛型问题。但是我打赌..不是。:) 假设我的类声明为: 问题答案: 你必须添加异常处理。 你必须在运行时传递实际类型,因为它不是编译后字节码的一部分,因此,没有显式提供它就无法知道它。

  • 我正在学习OOP的概念。在阅读继承的过程中,我了解到在初始化子类之前必须先初始化超类,即所有超类的构造函数必须在子类构造函数之前运行。此外,我们还可以直接创建超级类的实例。对于例如。 现在,我遇到了抽象类。看来我们不能实例化一个抽象类。要使用抽象类,您必须从另一个类继承它,并为其中的抽象方法提供实现。 我的问题是,在实例化具体子类的同时,抽象超类的构造函数会在具体子类的构造函数之前被调用。如果是这