如何避免由于空值而导致Google guice注入器getInstance()重复调用? [英] How to avoid Google guice injector getInstance() repetative calls due to null?

查看:200
本文介绍了如何避免由于空值而导致Google guice注入器getInstance()重复调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始使用Google guice DI框架,并且对它来说是一个新手。
我正面临以下问题-
@inject始终返回null,必须调用注入器来注入各种引用。

I have recently started using Google guice DI framework and am quite new to it. I am facing below problem - @inject returns null always and have to call injector to inject various references.

这是我的 AbstractModule


public class AppModule extends AbstractModule {

    private static final Injector injector = Guice.createInjector(new AppModule());

    private final Vertx vertx = Vertx.vertx(new VertxOptions().setMetricsOptions(
            new DropwizardMetricsOptions().setEnabled(true)
    ));

    private final com.test.reactivex.db.service.DBService dbService;

    public AppModule() {

        this.dbService = DBService.createProxy(this.vertx, DB_SERVICE_ADDRESS);
    }

    @Override
    protected void configure() {
        bind(Vertx.class).toInstance(this.vertx);
        bind(EventBus.class).toInstance(this.vertx.eventBus());
        bind(FileSystem.class).toInstance(this.vertx.fileSystem());
        bind(SharedData.class).toInstance(this.vertx.sharedData());
        bind(com.test.reactivex.db.service.DBService.class).toInstance(this.dbService);
        bind(AppConfig.class).toProvider(AppConfigProvider.class).in(Singleton.class);
        //requestStaticInjection(AppDependenciesInjector.class);
        logger.info("Google guice module configuration done");
    }

    @Provides
    public static AppConfig appConfig() {
        return injector.getInstance(AppConfig.class);
    }

    public static Injector getInjector() {
        return injector;
    }
}

这就是我使用注射器的方式注入依赖项,但问题是我必须再次使用注入器。

This is how I am using injector to inject dependencies, but problem is that I have to use injectors again.

public class GraphQLRouter {

    @Inject 
    private static AppConfig config;

    @Inject
    private com.test.reactivex.auth.service.DBService dbService;

    public GraphQLRouter() {
    // below code I want to avoid
        if (dbService == null) {
            dbService = AppModule.getInjector().getInstance(com.test.reactivex.auth.service.DBService.class);
        }
    }

    //below code I want to avoid
    static {
        if (config == null)
            config = AppModule.getInjector().getInstance(AppConfig.class);
    }


推荐答案

这将是答案很糟糕,但是随着更多信息的到来我将对其进行修改。这里的重要部分是:

This is going to be a terrible answer off the bat, but I'll modify it as more information comes in. The important piece here is that:

1)您的 GraphQLRouter 类使用基于字段的注入,这是因为 @Inject 在字段中,其中一个字段是静态的,这意味着您正在破坏它

1) Your GraphQLRouter class is using field based injection due to the @Inject being on the field, one of those fields is static, which means you're breaking it up even more.

2)然后,您尝试在构造函数中使用 dbService 可以正常工作-总是为空。

2) You're then attempting to use the dbService in your constructor, that's just never going to work - it's always going to be null.

这完全取决于您在哪里使用它。我对VertX几乎一无所知,因此,如果您需要更多有关该功能的信息,我将不得不进行谷歌搜索,但您不应混淆所有不同类型的注入(字段,构造函数,静态) 。

It all depends on where you're using it. I don't know (pretty much anything) about VertX, so if you need more with regards to that I'll have to do some googling, but you should not mix up all the different types of injections (field, constructor, static).

至少可以使用:

@Inject
public GraphQLRouter(AppConfig config, DBService dbService) {
    this.config = config;
    this.dbService = dbService;
}

在这一点上,为了进行测试,您处于更好的状态,但是我们仍然缺少从中创建实例的位置。

At this point you're in a better point for the purpose of testing, but we're still missing where you're creating the instance from.

编辑

我在Vert.x上做了一些阅读,想法,它们都牵扯着一条线

I did a little reading on Vert.x and had some ideas, they all involve pulling the line

private static final Injector injector = Guice.createInjector(new AppModule());

AppConfig 进入您的 public static void main(String [] args){} 方法。您在使用垂直行业吗?还是您在使用Vert.x而没有垂直行业?显然您可以做到,但是没有如何做的真实信息(因此我假设是前者)。同样,这只是一个想法,但是您需要向上移动注射器:

out of the AppConfig and into your public static void main(String[] args) {} method. Are you using Verticals? Or are you using Vert.x without verticals? Apparently you can do it, but there is no real information on how you would do it (so I'll assume the former). Again, this is just an idea, but you need to move the injector up:

public class RandomVerticle extends AbstractVerticle {

  @Inject
  private GraphQLRouter router;

  @Override
  public void start() {
     // use router
  }
}

public class Application {
   public static void main(String[] args) {
       private static final Injector injector = Guice.createInjector(new AppModule());

       Vertx vertx = injector.getInstance(Vertx.class);
       vertx.deployVerticle(injector.getInstance(RandomVerticle.class));
   }
}

这将要求您提供某种绑定Verticles,无论如何您都应该这样做。该文档讨论了能够使用 VerticleFactory 的方法,您可以自己实现以下目的:

This would require that you provide some kind of binding to the Verticles, which you should probably do anyhow. The documentation talks about being able to use a VerticleFactory which you could implement yourself so that:

vertx.deployVerticle("guice:com.example.SomeVerticle");

遇到了类似以下情况:

public class GuiceVerticleFactory implements VerticleFactory {
   public GuiceverticleFactory(Injector injector) {
       this.injector = injector;
   }
}

因此您可以在创建过程中注入顶点,我对工厂的关注不是很多,所以谁知道。

so you can inject the verticles during creation, but again, I didn't look into the Factory very much, so who knows.

希望它会有所帮助。

这篇关于如何避免由于空值而导致Google guice注入器getInstance()重复调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆