无法在 Dropwizard 应用程序中为 Guava Service Manager 创建注入器
Cannot create injector for Guava Service Manager in Dropwizard application
我想使用 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
对象,它与服务管理器交互以 start/stop 服务:
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
是依赖MyModule
的Dropwizard应用:
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)
这实质上意味着当应用程序为运行.
时,MZPaymentApplication
中注入的managedServices
为空
这里有什么问题?它与中的问题相同吗?如果是这样,@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));
}
}
我想使用 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
对象,它与服务管理器交互以 start/stop 服务:
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
是依赖MyModule
的Dropwizard应用:
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)
这实质上意味着当应用程序为运行.
时,MZPaymentApplication
中注入的managedServices
为空
这里有什么问题?它与@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));
}
}