首页 > 解决方案 > 如何用 Guice 注入 Hk2 bean

问题描述

有一个基于球衣的 dropwizard 应用程序。我将 Hk2 bean 定义重写为 Guice,现在我可以将 Guice bean 注入 Jersey Resources,但我注意到在 dropwizard 包中定义的 Hk2 bean,我无法重写,Guice 看不到它,它无法注入在 Hk2 中定义的依赖项。
Guice 没有看到 Hk2 包中定义的 bean,Guice 默认创建新的未初始化的 bean。我用 requireExplicitBindings 禁用了这种行为。

我尝试了 HK2IntoGuiceBridge,但它的匹配器没有为我感兴趣的 bean 调用。ConfiguredBundleX 位于外部工件中。

我试图从包中复制和翻译 bean 定义并坚持使用 jersey bean Provider<ContainerRequest>,我不知道它来自哪里。

public class ConfiguredBundleX implements ConfiguredBundle<MyAppConf> {
  public void run(T configuration, Environment environment) throws Exception {
    environment.jersey().register(new AbstractBinder() {
            protected void configure() {
                this.bind(new MyHk2Bean()).to(MyHk2Bean.class);
            }
        });
  }  
}

public class DependsOnHk2Bean { @Inject public DependsOnHk2Bean(MyHk2Bean b) {} }

public class MainModule extends AbstractModule {
    private final ServiceLocator locator;
    protected void configure() {
      binder().requireExplicitBindings();

      install(new HK2IntoGuiceBridge(locator));
      bind(DependsOnHk2Bean.class);
}

public class GuiceFeature implements Feature {
    public boolean configure(FeatureContext context) {
        ServiceLocator locator = ServiceLocatorProvider.getServiceLocator(context);
        GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
        Injector injector = Guice.createInjector(
                new HK2IntoGuiceBridge(locator),
                new MainModule(locator));

        GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
        guiceBridge.bridgeGuiceInjector(injector);
        return true;
    }
}
// ...

 public void initialize(Bootstrap<X> bootstrap) {
   bootstrap.addBundle(new ConfiguredBundleX());
 }

 public void run(X config, Environment env) {
   env.jersey().register(new GuiceFeature());
 }

标签: javaguicedropwizardhk2

解决方案


在挖掘 Guice 和 HK2ToGuiceTypeListenerImpl 之后,我发现有 bindListener 可以拦截丢失的绑定并将它们从某个地方拉出来。@HKInject 代码在那里,但我注意到没有为某些 bean 调用侦听器,包括我感兴趣的 bean。是的 HKInject 不支持构造函数注入(4.2.1 版本)

所以我决定手动导入 HK bean 并在 Guice 中绑定它们。Dropwizard 术语很糟糕,有些方法获取上下文,获取管理上下文完全不同,bean 必须使用 getService 方法获取!

@RequiredArgsConstructor
public class HkModule extends AbstractModule {
    private final ServiceLocator locator;

    @Override
    protected void configure() {
        binder().requireExplicitBindings();

        Provider<Bar> barProvider = locator.getService(
                new TypeLiteral<Provider<Bar>>(){}.getType());
        bind(Bar.class).toProvider(barProvider);
        bind(Foo.class).toInstance(locator.getService(Foo.class));
    }
}


推荐阅读