0

我已经阅读了用户指南和所有内容,但我仍然不明白如何在尝试注入依赖项时修改现有代码以使用 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 GuiceobjectA在构造函数中提取创建,B()而不是将其作为依赖项注入到 B 类中,它相当于

@Inject    
public B() {
}  

我将如何实际将 A 的实例注入其中?

4

3 回答 3

3

首先, 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与称为模块的特殊类中的接口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);

    }
}
于 2013-10-15T01:52:34.760 回答
2

您可以通过两种方式将 A 注入 B,实际上有多种方式,但在您的问题的上下文中,我会说两种。

  1. 确保在模块中配置了 A 类和 B 类。遵循扩展 AbstractModule 的条件示例代码/类。

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;
    }

} 
于 2013-10-15T02:45:56.433 回答
0

这是一个基于您已有的示例:

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;
    }

    ...
  }
于 2013-10-15T01:25:29.747 回答