- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
[Guice 4.0]
我想要一个泛型类的接口(interface),并通过 Guice 在依赖注入(inject)中使用它。对于下面列出的代码,我收到以下错误:
Exception in thread "main" com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Could not find a suitable constructor in com.ulmon.fsqtransit.guicetest.Class1. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.ulmon.fsqtransit.guicetest.Class1.class(Class1.java:14)
at com.ulmon.fsqtransit.guicetest.Module.configure(Module.java:14)
--
public class Class1<T1 extends Number, T2 extends Number>
implements InterfClass1<T1, T2> {
public static final String ANNOT1 = "ANNOT1";
public static final String ANNOT2 = "ANNOT2";
private T1 t1;
private T2 t2;
// for the factory
@AssistedInject
public Class1(
@Assisted(Class1.ANNOT1) T1 t1,
@Assisted(Class1.ANNOT2) T2 t2
) {
this.t1 = t1;
this.t2 = t2;
}
public T1 getT1() {
return t1;
}
public T2 getT2() {
return t2;
}
}
public class Module extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<InterfClass1<Integer, Integer>>(){})
.to(new TypeLiteral<Class1<Integer, Integer>>(){});
}
public static void main(String[] args) {
Injector inj = Guice.createInjector(new Module());
}
}
什么原因导致此错误?
让我们添加工厂并修改模块(从模块中删除 InterfClass1 接口(interface)):
public interface Class1Factory<T1 extends Number, T2 extends Number> {
public Class1<T1, T2> createClass1(
@Assisted(Class1.ANNOT1) T1 t1,
@Assisted(Class1.ANNOT2) T2 t2
);
}
public class Module extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder()
.build(new TypeLiteral<Class1Factory<Integer, Double>>(){}));
}
public static void main(String[] args) {
Injector inj = Guice.createInjector(new Module());
Class1Factory f = inj.getInstance(Key.get(new TypeLiteral<Class1Factory<Integer, Double>>(){}));
f.createClass1(10, 11.0);
}
}
效果很好!
现在让我们合并界面:
public class Module extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<InterfClass1<Integer, Double>>(){})
.to(new TypeLiteral<Class1<Integer, Double>>(){});
install(new FactoryModuleBuilder()
.build(new TypeLiteral<Class1Factory<Integer, Double>>(){}));
}
public static void main(String[] args) {
Injector inj = Guice.createInjector(new Module());
Class1Factory f = inj.getInstance(Key.get(new TypeLiteral<Class1Factory<Integer, Double>>(){}));
f.createClass1(10, 11.0);
}
}
我们得到:
1) Could not find a suitable constructor in com.ulmon.fsqtransit.guicetest.Class1. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.ulmon.fsqtransit.guicetest.Class1.class(Class1.java:15)
at com.ulmon.fsqtransit.guicetest.Module.configure(Module.java:14)
好吧,不管错误如何,我们也更改工厂:
public interface Class1Factory<T1 extends Number, T2 extends Number> {
public InterfClass1<T1, T2> createClass1(
@Assisted(Class1.ANNOT1) T1 t1,
@Assisted(Class1.ANNOT2) T2 t2
);
}
我们得到:
1) Could not find a suitable constructor in com.ulmon.fsqtransit.guicetest.Class1. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
at com.ulmon.fsqtransit.guicetest.Class1.class(Class1.java:15)
at com.ulmon.fsqtransit.guicetest.Module.configure(Module.java:14)
2) com.ulmon.fsqtransit.guicetest.InterfClass1<java.lang.Integer, java.lang.Double> is an interface, not a concrete class. Unable to create AssistedInject factory.
while locating com.ulmon.fsqtransit.guicetest.InterfClass1<java.lang.Integer, java.lang.Double>
at com.ulmon.fsqtransit.guicetest.Class1Factory.createClass1(Class1Factory.java:1)
但是,如果我删除模块中接口(interface)和类之间的关系并将此关系添加到工厂的规范中,则不会出现错误:
public class Module extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder()
.implement(new TypeLiteral<InterfClass1<Integer, Double>>(){}
, new TypeLiteral<Class1<Integer, Double>>(){})
.build(new TypeLiteral<Class1Factory<Integer, Double>>(){}));
}
public static void main(String[] args) {
Injector inj = Guice.createInjector(new Module());
Class1Factory f = inj.getInstance(Key.get(new TypeLiteral<Class1Factory<Integer, Double>>(){}));
f.createClass1(10, 11.0);
}
}
效果很好!
为什么 Guice 有这种奇怪的行为?为什么无论工厂如何,我都无法将接口(interface)与实现类关联起来?
最佳答案
我无法确切地弄清楚您想要做什么,但在我看来,您实际上并没有尝试创建 AssistedInject 工厂,因为您还没有为工厂创建接口(interface)。在这种情况下,您根本不需要使用 @Assisted
参数。您的构造函数应如下所示(对该类没有其他更改):
@Inject
public Class1(
@Named(Class1.ANNOT1) T1 t1,
@Named(Class1.ANNOT2) T2 t2
) {
然后,指定模块中的绑定(bind)。您必须明确告诉 Guice 为参数注入(inject)什么以及您指定的注释:
@Override
protected void configure() {
bind(new TypeLiteral<InterfClass1<Integer, Integer>>(){})
.to(new TypeLiteral<Class1<Integer, Integer>>(){});
bind(Integer.class)
.annotatedWith(Names.named(Class1.ANNOT1))
.toInstance(5);
bind(Integer.class)
.annotatedWith(Names.named(Class1.ANNOT2))
.toInstance(15);
}
然后,我们可以像这样运行它:
public static void main(String[] args) {
Injector inj = Guice.createInjector(new Module());
InterfClass1<Integer, Integer> interf =
inj.getInstance(Key.get(new TypeLiteral<InterfClass1<Integer, Integer>>(){}));
System.out.println(interf.getClass());
System.out.println("T1: " + interf.getT1() + " T2: " + interf.getT2());
}
正如您在运行它时所看到的,它将注入(inject)一个 Class
实现,并指定两个参数:
class guice.Class1
T1: 5 T2: 15
<小时/>
如果您尝试使用 AssistedInject 构建 Class1
对象工厂,则由于您指定 Generit 类型参数的方式,这会变得更加困难。不幸的是,你不能inject a generic factory using AssistedInject in the normal way ,这会变得更加困难,因为您的 Class1
实现需要 T1 extends Number
,但您的接口(interface)可以是您想要的任何 T1
。这意味着您的工厂必须将其接收的输入参数的类型限制为 Number
的子类;换句话说,您的工厂不能只创建它想要的任何 InterfClass1
,它只能创建具有正确输入参数的实例。
希望答案的前半部分就是您想要做的。如果不是,我们需要有关您的用例的更多信息才能回答此问题。
关于java - 如何将接口(interface)与通用类的实现绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31807055/
我有一个 foo 类,它有一个 bar 方法,它接受可调用的东西(函数指针/仿函数)。这个可调用的东西应该作为绑定(bind)元素传递给另一个方法 doit 和第三个方法 bar_cb 方法。 #in
我正在尝试在我的 WPF 4.0 应用程序(使用 VS 2010 Pro RTM)中创建自定义 TabItem 模板/样式,但尽管一切似乎都正常工作,但我注意到跟踪窗口中存在绑定(bind)错误。 我
作为一名刚接触 Android 的开发人员,我想我可能误解了绑定(bind)服务。 我创建了一项服务来结束对服务器的访问。作为此服务的一部分,该服务正在监听多播地址,以识别本地网络上的设备何时出现和消
这个问题在这里已经有了答案: What is the use of the JavaScript 'bind' method? (23 个回答) 关闭 7 年前。 所以我一直在尝试了解一些 JS 上
我不明白这三种语法之间的区别: where a = f (b) do a <- f (b) do let a = f (b) 我确实明白了a <- f(b)与其他两个不同,在大多数情况下,我尝试了所有
我在将 Cocoa 项目从手动同步接口(interface)模型转换为绑定(bind)模型时遇到问题,这样我就不必担心接口(interface)粘合代码。 我关注了 CocoaDevCentral C
我正在尝试找出一种好的方法来对处理大数据集的代码进行并行化,然后将结果数据导入 RavenDb。 数据处理受 CPU 限制和数据库导入 IO 限制。 我正在寻找一种解决方案,以对 Environmen
我正在 foreach 循环中生成单选按钮。我试图将选中的属性绑定(bind)到父级中的基本可观察值。不幸的是,当单击单选按钮时,父级的属性似乎没有在单击处理程序中更新。 基于一些previous w
在我的 Windows Phone 应用程序中,我有两个 LongListSelectors并排在页面上。我想做到这一点,以便当用户滚动其中一个时,另一个滚动相同的量。 两个 LongListSele
我在网上看到这个问题准备面试: Given a non-preemptive kernel which type of process will get affected morein terms o
我有一个 foreach 绑定(bind),如下所示: Summary Permitting 原因是有两个选项卡始终存在,并且我根据是否添加了其他选项卡来添加其他选项
任何人都有绑定(bind)相同的情况DataContext到 TextBlock 中的 Text 属性(例如)。 我必须分配 DataContext以我的风格反射(reflect)基于 Datacon
给定以下代码: Login 和下面的javascript $(function () { $('#btnLogin').click(function () { co
我使用 boost::asio 创建了一个服务器。我在绑定(bind)到端点时遇到问题。所以,如果我在构造函数中初始化一个接受器: Server::Server(QWidget *parent) :
我正在将现有项目从 MySQL 转换为 Postgres。代码中有相当多的原始 SQL 文字使用 ? 作为占位符,例如 SELECT id FROM users WHERE
似乎在绑定(bind)某些数据时出错了,有人可以帮我解决我哪里出错了,尽管我无法弄清楚。 真的不需要在这里显示太多,这是 Binding,我已经通过移除背景并在其中放置颜色来测试背景,效果很好。 编辑
我正在尝试使用 wcf 构建一个 http 监听器(web 服务)。这个监听器是一个更大的桌面应用程序的一部分。此桌面应用程序还会调用 http 监听器。 当监听器接收到数据时,它应该被传递到桌面应用
嘿嘿。 我正在使用 Node.JS 和 child_process 来生成 bash 进程。我试图了解我是否正在执行 I/O 绑定(bind)、CPU 绑定(bind)或两者兼而有之。 我正在使用 p
尝试执行以下操作并出现“Got interpolation ({{}}) where expression was expected”错误。 {{item.name}} 谢谢!
我有一个导入的 Java 库,它是我解决方案中的“绑定(bind)库”项目。 我正在尝试从解决方案中的另一个项目绑定(bind)到第 3 方库中的服务。 第 3 方库文档 [在 java 中] 非常简
我是一名优秀的程序员,十分优秀!