简体   繁体   English

如何用 Guice 注入 Hk2 bean

[英]How inject Hk2 beans with Guice

There is a dropwizard app, which is jersey based.有一个基于 jersey 的 dropwizard 应用程序。 I rewrote Hk2 bean definitions into Guice and now I can inject Guice beans into Jersey Resources, but I noticed that Hk2 beans, defined in dropwizard bundles, which I cannot rewrite, are not visible by Guice and it fails to inject dependencies defined in Hk2.我将 Hk2 bean 定义重写到 Guice,现在我可以将 Guice bean 注入 Jersey 资源,但我注意到在 dropwizard 包中定义的 Hk2 bean,我无法重写,Guice 不可见,它无法注入在 Hk2 中定义的依赖项。
Guice doesn't see beans defined in Hk2 bundles and Guice creates new uninitialized beans by default. Guice 没有看到 Hk2 包中定义的 bean,Guice 默认创建新的未初始化的 bean。 I disabled this behavior with requireExplicitBindings.我用 requireExplicitBindings 禁用了这种行为。

I experimented with HK2IntoGuiceBridge, but its matcher is not invoked for beans I am interested in. ConfiguredBundleX is located in external artifact.我尝试了 HK2IntoGuiceBridge,但它的匹配器没有为我感兴趣的 bean 调用。ConfiguredBundleX 位于外部工件中。

I tried to copy and translate bean definitions from bundles and stuck with jersey bean Provider<ContainerRequest> , I have no idea where it comes from.我试图从包中复制和翻译 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());
 }

Unfortunately in Guice beans you have to use @HK2Inject rather than @Inject in order to inject hk2 beans into Guice.不幸的是,在 Guice bean 中,您必须使用 @HK2Inject 而不是 @Inject 才能将 hk2 bean 注入 Guice。 So in your code above you would do:所以在你上面的代码中你会这样做:

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

This is because of limitation in guice (it may be fixed by now) such that @Inject behavior could not overwritten这是因为 guice 的限制(现在可能已修复),因此无法覆盖 @Inject 行为

I have not tried the above code myself so I'm not sure it'll work, but that was the deal back when the bridge was written...我自己没有尝试过上面的代码,所以我不确定它会起作用,但那是写桥时的交易......

See HK2Inject and injecting-hk2-services-into-guice-services请参阅HK2Inject和 injection -hk2-services-into-guice-services

After digging Guice and HK2ToGuiceTypeListenerImpl I figured out that there is bindListener to kind of intercept missing bindings and pull them from somewhere.在挖掘 Guice 和 HK2ToGuiceTypeListenerImpl 之后,我发现有 bindListener 可以拦截丢失的绑定并将它们从某个地方拉出来。 @HKInject code is there, but I noticed that the listener is not called for some bean including the bean I was interested in. Yes HKInject doesn't support constructor injection (4.2.1 version) @HKInject 代码在那里,但我注意到没有为某些 bean 调用侦听器,包括我感兴趣的 bean。是的 HKInject 不支持构造函数注入(4.2.1 版本)

So I decided to manually import HK beans and bind them in Guice.所以我决定手动导入 HK bean 并在 Guice 中绑定它们。 Dropwizard terminology is horrible there are methods get context something, get admin context is totally something different and beans must be get with getService method! 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));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM