如何使用 Guice 很好地处理构造函数中的检查异常?
我的代码如下所示:
class A {
X x;
A() {
Class<? extends X> cls = ...;
Module module = ...;
Injector injector = Guice.createInjector(module);
x = injector.getInstance(cls);
}
}
具体类型 cls
仅在运行时确定,并且在调用此构造函数之前不知道。
我现在的问题是 cls 的构造函数预计会抛出已检查的异常,并且我想处理它们(如果可能的话,不要从 ProvisionException 中解开它们)。 Guice 文档说我应该使用 throwing 提供程序扩展,这在这里似乎很复杂。有没有比这更简单的方法:
interface MyCheckedProvider<T> extends CheckedProvider<T> {
T get() throws MyCheckedException;
}
class XImplProvider implements MyCheckedProvider<X> {
@Inject dependency1;
@Inject dependency1;
X get() throws MyCheckedException {
return new XImpl(dependency1, dependency2);
}
}
class ProviderHolder {
@Inject MyCheckedProvider<X> provider;
}
class A {
X x;
A() {
Class<? extends MyCheckedProvider<X>> providerClass = ...;
Module module = new AbstractModule() {
void configure() {
...
ThrowingProviderBinder.create(binder())
.bind(MyCheckedProvider.class, X.class)
.to(providerClass.class);
}
};
Injector injector = Guice.createInjector(module);
ProviderHolder holder = injector.getInstance(ProviderHolder.class);
try {
x = holder.provider.get();
catch (MyCheckedException e) {
...
}
}
}
接口 MyCheckedProvider
就可以了,因为它可以在多个地方重用,但我在每个地方都需要一个单独的 ProviderHolder
类需要类似的东西,并且我需要为每个实现 X 的类(可能有很多)提供特定的提供程序实现。因此,这比仅仅注入 XFactory 并为每个具体类型编写 XFactoryImpl(我试图避免)还要更多的工作。
我曾希望我可以做类似
injector.getInstance(new TypeLiteral<MyCheckedProvider<X>>() {});
or 的
injector.getCheckedProvider(cls, MyCheckedException.class);
事情,但似乎这不受支持。
I have code that reads like this:
class A {
X x;
A() {
Class<? extends X> cls = ...;
Module module = ...;
Injector injector = Guice.createInjector(module);
x = injector.getInstance(cls);
}
}
The concrete type cls
is determined only at runtime and not known before this constructor is called.
My problem now is that the constructors of cls
are expected to throw checked exceptions, and I'd like to handle them (if possible without unwrapping them from a ProvisionException). The Guice documentation says I should use the throwing providers extension, which seems to be complex here. Is there a simpler way than this:
interface MyCheckedProvider<T> extends CheckedProvider<T> {
T get() throws MyCheckedException;
}
class XImplProvider implements MyCheckedProvider<X> {
@Inject dependency1;
@Inject dependency1;
X get() throws MyCheckedException {
return new XImpl(dependency1, dependency2);
}
}
class ProviderHolder {
@Inject MyCheckedProvider<X> provider;
}
class A {
X x;
A() {
Class<? extends MyCheckedProvider<X>> providerClass = ...;
Module module = new AbstractModule() {
void configure() {
...
ThrowingProviderBinder.create(binder())
.bind(MyCheckedProvider.class, X.class)
.to(providerClass.class);
}
};
Injector injector = Guice.createInjector(module);
ProviderHolder holder = injector.getInstance(ProviderHolder.class);
try {
x = holder.provider.get();
catch (MyCheckedException e) {
...
}
}
}
The interface MyCheckedProvider
would be ok, because it would be reusable in several places, but I'd need a separate ProviderHolder
class at each place where something similar is needed, and I need a specific provider implementation for each class implementing X (of which there could be many). So this is even more work than just injecting an XFactory and writing an XFactoryImpl for each concrete type (which I tried to avoid).
I had hoped that I can do something like
injector.getInstance(new TypeLiteral<MyCheckedProvider<X>>() {});
or
injector.getCheckedProvider(cls, MyCheckedException.class);
but it seems this is not supported.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您想在此处使用
Key
类,而不是TypeLiteral
。那么就不需要ProviderHolder
:You want to use the
Key
class here, notTypeLiteral
. Then there is no need forProviderHolder
: