2013-10-15 40 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