【问题标题】:Cant Inject same instance to multiple Verticles using Guice and Vertx to无法使用 Guice 和 Vertx 将相同的实例注入到多个 Verticle
【发布时间】:2015-09-15 13:46:04
【问题描述】:

我有 3 个vertx verticles。

我创建了实现类 A 的类 AImpl,如下所示

 @Singleton
public class AImpl implements A {


    public LocationServiceImpl() {
        System.out.println("initiated once");

    }

 public void doSomething(){..}

Verticle 1 如下所示:

public class MyVerticle1 extends AbstractVerticle {
...
 @Inject
    private A a;


 @Override
    public void start(Future<Void> fut) {
 Guice.createInjector(new AppInjector()).injectMembers(this);
  a.doSomething(..);

..}

MyVerticle2 和 MyVerticle3 看起来一样。

Guice 代码:

public class AppInjector extends AbstractModule {


    public AppInjector() {
    }


    @Override
    protected void configure() {   
 bind(A.class).to(AImpl.class).in(Singleton.class);

    }

现在,当我运行 vertx 时,我可以看到我得到了 3 个不同的 AImpl 实例:

 public static void main(String[] args) throws InterruptedException {
        final Logger logger = Logger.getLogger(StarterVerticle.class);
        ClusterManager mgr = new HazelcastClusterManager();
        VertxOptions options = new VertxOptions().setClusterManager(mgr);
        Vertx.clusteredVertx(options, res -> {
            if (res.succeeded()) {
                Vertx vertx = res.result();
                vertx.deployVerticle(new MyVerticle1());
                vertx.deployVerticle(new MyVerticle2());
                vertx.deployVerticle(new MyVerticle3());
                logger.info("Vertx cluster started!");
            } else {
                logger.error("Error initiating Vertx cluster");
            }
        });

控制台:

2015-09-15 16:36:15,611 [vert.x-eventloop-thread-0] INFO   - Vertx cluster started!
initiated once
initiated once
initiated once

我在滥用什么?为什么我没有得到相同的 AImpl 实例?

谢谢, 射线。

【问题讨论】:

    标签: java dependency-injection guice vert.x


    【解决方案1】:

    您以错误的方式使用 guice。您正在通过 new 创建 MyVerticle 实例,并在它们的启动消息中创建注入器。因此,您最终会得到 3 个注入器,每个注入器都有一个单例。

    您必须在 main() 方法中创建一次注入器,然后让 guice 处理 MyVerticles 的创建:

    Injector injector = Guice.createInjector(....);
    ...
    vertx.deployVerticle(injector.getInstance(MyVerticle1.class);
    

    现在注入器只为 AImpl 创建一个实例,并将其重用于所有@Inject AImpl 位置。完全从您的启动方法中删除注入器。

    使用 guice 时的两条经验法则:

    1. 避免使用new
    2. 尝试在 main() 方法中仅使用一个注入器

    【讨论】:

    • 感谢您的回复。你能举一个具体的例子吗?我不确定我应该如何在没有新的情况下创建我的 verticles 以及我应该如何在 Guice 上定义 tham
    • 接受是否意味着你想通了,还是我还应该举个例子?
    • 我想通了。我只想听听您的解释,您的答案实际上是如何解决的?猜猜我错过了我的理解和Guice。谢谢。
    • 您通过 Guice.create 创建的注入器基本上包含类型和实例的映射。所以你的单例实例在其他注入器中不可用。当您为每个 Verticle 创建一个注入器时,它们没有共享任何东西。现在,您正在应用程序根目录上创建一个注入器,然后可以管理所有类的实例生成和范围。
    • 最佳实践是每个verticle实例都有一个全局Guice注入器或注入器吗?我假设每个verticle实例的注入器应该没问题,因为verticles是自包含的,你有一个'singleton-per-verticle'而不是全局singleton。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多