如何使用Google Guice注入依赖项

时间:2013-10-15 01:05:12

标签: java guice roboguice

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

@Inject    
public B() {
}  

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

3 个答案:

答案 0 :(得分: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 绑定到名为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);

    }
}

答案 1 :(得分:2)

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

  1. 确保在模块中配置A和B类。遵循扩展AbstractModule的condit示例代码/类。
  2. 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;
        }
    
    } 
    

答案 2 :(得分: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;
    }

    ...
  }