无法在Dropwizard应用程序中为Guava Service Manager创建注入器



我想使用Guava的服务管理器来管理Dropwizard应用程序中的服务。

ServiceManagerProvider提供服务管理器:

@Singleton
public class ServiceManagerProvider implements Provider<ServiceManager> {
@Inject
Set<Service> services;
public static Multibinder<Service> serviceRegistry(Binder binder) {
return Multibinder.newSetBinder(binder, Service.class);
}
@Override
public ServiceManager get() {
return new ServiceManager(services);
}
}

ManagedGuavaServices是一个Managed对象,它与服务管理器交互以启动/停止服务:

public class ManagedGuavaServices implements Managed {
@Inject
private ServiceManager _serviceManager;
@Inject
public ManagedGuavaServices(ServiceManager serviceManager) {
_serviceManager = serviceManager;
}
@Override
public void start() throws Exception {
_serviceManager.startAsync();
}
@Override
public void stop() throws Exception {
_serviceManager.stopAsync();
}
}

MyModule是指定Guice绑定的模块:

public class MyModule extends DropwizardAwareModule<MyConfig> {
...
@Override
protected void configure() {
bind(ServiceManager.class).toProvider(ServiceManagerProvider.class);
bind(Managed.class).to(ManagedGuavaServices.class).in(Singleton.class);
}
}

MyApplication是Dropwizard应用程序,它依赖于MyModule:

public class MyApplication extends Application<MyConfig> {
@Inject
private Managed managedServices;
...
@Override
public void initialize(Bootstrap<MyConfig> bootstrap) {
bootstrap.addBundle(GuiceBundle.builder()
.printDiagnosticInfo()
.printGuiceBindings()
.enableAutoConfig(getClass().getPackage().getName())
.modules(
new MyModule()
)
.build());
}
...
@Override
public void run(MyConfig config, Environment environment) {
environment.lifecycle().manage(managedServices);
}
}

似乎所有的东西都连接在一起了,但当我运行应用程序时,我会收到错误消息:

java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at io.dropwizard.lifecycle.setup.LifecycleEnvironment.manage(LifecycleEnvironment.java:45)
at com.example.MyApplication.run(MyApplication.java:188)
at com.example.MyApplication.run(MyApplication.java:60)
at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:44)
at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:87)
at io.dropwizard.cli.Cli.run(Cli.java:78)
at io.dropwizard.Application.run(Application.java:94)
at com.example.MyApplication.main(MyApplication.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.webobjects._bootstrap.WOBootstrap.main(WOBootstrap.java:118)

这实质上意味着当应用程序运行时CCD_ 8中注入的CCD_。

这里怎么了?这和这个SO问题是同一个问题吗?如果是,@PostConstruct应该在哪里?

问题在于managedServices是应用程序中的字段,不可注入,因为应用程序对象不是由Guice配置的(通常在Dropwizard中,它是通过new关键字创建的(。因此,您应该将GuiceBundle实例存储在initialize方法中作为字段,然后使用guiceBundle.getInjector().getInstance()访问run方法中的任何Guice绑定,例如:

public class MyApplication extends Application<MyConfig> {
private GuiceBundle<MyConfig> guiceBundle;
public static void main(String[] args) throws Exception {
new MyApplication().run(args);
}
@Override
public void initialize(Bootstrap<MyConfig> bootstrap) {
guiceBundle = GuiceBundle.builder()
.printDiagnosticInfo()
.printGuiceBindings()
.enableAutoConfig(getClass().getPackage().getName())
.modules(
new MyModule()
)
.build();
bootstrap.addBundle(guiceBundle);
}
@Override
public void run(MyConfig config, Environment environment) throws Exception {
environment.lifecycle().manage(guiceBundle.getInjector().getInstance(Managed.class));
}
}

最新更新