如何避免由于空值而导致Google guice注入器getInstance()重复调用? [英] How to avoid Google guice injector getInstance() repetative calls due to null?
问题描述
我最近开始使用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屋!