java - 如何用 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());
}
解决方案
在挖掘 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));
}
}
推荐阅读
- flutter - 如何在 MobX Flutter 中对复杂结构运行反应
- react-native - React-Native:是否有可能在一次调用中关闭所有打开的模态?
- activemq - ActiveMQ 中可以创建多少个队列?
- google-chrome-extension - 如何在 chrome 扩展中实现谷歌标签管理器代码?
- apache-kafka - 避免Kafka数据中心之间重复数据处理
- javascript - 努力将 nodemailer 配置为将 gmail 与 oAuth2 一起使用
- ballerina - 芭蕾舞女演员 Java 演员异常
- javascript - 如何在javascript中将大小/数字分解为一个对象?
- java - java:Visual Studio Code 不读取文件
- java - 将 DynamoJson 转换为与 Dynamo 客户端兼容的东西