簡體   English   中英

如何使用Google Guice注入依賴關系

[英]How to use Google Guice to inject a dependancy

我已經閱讀了用戶指南和所有內容,但在嘗試注入依賴項時,我仍然不完全了解如何修改現有代碼以使用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創建, objectA其作為依賴項注入到Class 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);
    }
}

我刪除了static修飾符,但是如果您堅持要使用靜態修飾符,則需要使用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);

    }
}

您可以通過兩種方式將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;
    }

}

兩者都可以正常工作,但是1.b對於要為類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;
    }

    ...
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM