我已经浏览了用户指南和所有内容,但我仍然不明白在尝试注入依赖项时如何修改现有代码以使用 Google Guice。因此,为了更容易,我创建了这个简单的例子,如果有人可以用这个简单的例子来解释,我将不胜感激!
假设我有一个
public Class A {
private int count = 0;
public A() {
}
public int getCount() {
return count;
}
public void setCount(int newCount) {
this.count = newCount;
}
}
和另一个类
public Class B {
private A objectA;
public B() {
objectA = new A();
}
public void messWithCount() {
int tempCount = objectA.getCount();
objectA.setCount(tempCount+1);
}
}
所以基本上我的问题是:我将如何使用 Google Guice 在构造函数B()
中提取objectA
的创建,并将其作为依赖项注入到 B 类中,它相当于类似
@Inject
public B() {
}
我将如何实际将 A 的实例注入其中?
首先,B 不应该绑定到 A 类,而应该使用接口(例如 AInterface)。Guice 的要点是绑定同一接口的不同实现,而不绑定到某个类。
因此,让我们假设A类实现了AInterface。
interface AInterface {
public int getCount();
public void setCount(int newCount);
}
class A implements AInterface {
private int count = 0;
public A() {
System.out.println("done!");
}
@Override
public int getCount() {
return count;
}
@Override
public void setCount(int newCount) {
this.count = newCount;
}
}
现在你告诉它注入你的变量:
class B {
@Inject
private AInterface objectA;
public B() {}
public void messWithCount() {
int tempCount = objectA.getCount();
objectA.setCount(tempCount + 1);
}
}
我删除了静态修饰符,但如果你坚持让它保持静态,你需要使用 requestStaticInjection 来绑定
您将实现 A 绑定到名为 module 的特殊类中的接口 AInterface:
class SimpleModule extends AbstractModule {
@Override
protected void configure() {
bind(AInterface.class).to(A.class);
}
}
现在你让Guice为你生成B。
public class Temptemp {
public static void main(String[] args) {
Injector i = Guice.createInjector(new SimpleModule());
B b = i.getInstance(B.class);
}
}
您可以通过两种方式将 A 注入 B 中,实际上有很多方法,但在您的问题的上下文中,我会说两种。
- 确保在模块中同时配置了 A 类和 B 类。遵循扩展 AbstractModule 的 condit 示例代码/类。
1.a
class B {
@Inject
private A a;
public B() {
}
}
1.b
class B {
private A a;
@Inject
public B(A a) {
this.a = a;
}
}
这些都工作正常,但如果你想为 B 类编写测试,1.b 很有用。您的测试将模拟 A 类并创建 B 的实例。
class BTest {
@Test
public void testSomeMethodOfB() {
A a = mock(A.class);
B b = new B(a);
//run some test on b;
}
}
下面是一个基于您已有内容的示例:
public class GuiceExample {
static class A {
private int count = 0;
public A() {}
public int getCount() {
return count;
}
public void setCount(int newCount) {
this.count = newCount;
}
}
static class B {
@Inject
private static A objectA;
public B() {}
public void messWithCount() {
int tempCount = objectA.getCount();
objectA.setCount(tempCount+1);
}
}
static class Module extends AbstractModule {
@Override
protected void configure() {
requestStaticInjection(B.class);
}
}
@Test
public void test() {
Injector i = Guice.createInjector(new Module());
B b = i.getInstance(B.class);
//Do something with b
}
}
但请注意,静态注入不是首选。你可以使 A 成为非静态的,Guice 仍然会注入字段。更"正确"的方法是删除requestStaticInjection
调用并添加 A 作为构造参数,例如:
static class B {
private A objectA;
@Inject
public B(A objectA) {
this.objectA = objectA;
}
...
}