2013-10-15 21 views
0

我已经通过用户指南和一切,但我仍然不明白如何修改现有的代码来尝试注入依赖时使用谷歌的Guice。所以为了使它更容易,我创建了这个简单的例子,如果有人可以用这个简单的例子来解释我会很感激!如何使用谷歌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); 
    } 
} 

所以基本上我的问题是:我将如何去使用谷歌吉斯在构造函数中提取objectA创建B(),而是注入它作为B类依赖项,它将相当于类似于

@Inject  
public B() { 
} 

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

+0

你有没有通过教程和介绍视频呢?我会从那里开始。另外,你的A变量不应该是静态的。 –

+0

是的,我走过教程,我觉得它只是更复杂。因为它解释了如何单独完成不同的部分,但并没有真正解释它们是如何在最终的最终产品中一起工作的,而这正是我仍然难以找到的结果。 – user2880807

回答

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电话,并添加施工参数,如:

static class B { 
    private A objectA; 

    @Inject 
    public B(A objectA) { 
     this.objectA = objectA; 
    } 

    ... 
    } 
+0

您是否想要requestStaticInjection(** A **。类)?而不是B.class?因为否则我没有看到A在你的注入中实​​际涉及到了哪些内容 – user2880807

+0

否 - 你想在'B'中静态注入(因为'A'是一个静态成员)。在具有无参数构造函数的类(如'A')上添加'@ Inject'注释是可选的。 – condit

3

首先,B不应该被绑定到A级,而是使用一个接口(如A接口 )。 Guice的主要观点是绑定相同接口的不同实现,而不被绑定到某个类。

因此,让我们假设A类实现A接口

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

我删除static修饰符,但如果你有坚持它静态你需要绑定使用requestStaticInjection而不是

你配合实施一个到接口A接口一类特殊的称为模块:

class SimpleModule extends AbstractModule { 

    @Override 
    protected void configure() { 
     bind(AInterface.class).to(A.class); 
    } 
} 

现在你问吉斯生成B中你。

public class Temptemp { 
    public static void main(String[] args) { 
     Injector i = Guice.createInjector(new SimpleModule()); 
     B b = i.getInstance(B.class); 

    } 
} 
+0

'AInterface'在这里绝对不是必需的。 Guice完美无缺地工作。 –

2

你可以注入一个分为B两种方式,实际上很多方面,但在你的问题的方面,我会说两句。

  1. 确保在模块中配置了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是有用的,你的测试将模拟一个类并创建B的实例。就像

class BTest { 

    @Test 
    public void testSomeMethodOfB() { 
     A a = mock(A.class); 
     B b = new B(a); 
     //run some test on b; 
    } 

} 
+0

只要有可注入构造函数(无参数或带有@Inject注释),就不需要向模块添加类。如果你想注入一个接口或一个子类,该模块很有用 – nicopico