java輕量級IOC框架Guice

来源:http://www.cnblogs.com/cainiaomahua/archive/2016/11/19/6080966.html
-Advertisement-
Play Games

Google-Guice入門介紹(較為清晰的說明瞭流程):http://blog.csdn.net/derekjiang/article/details/7231490 使用Guice,需要添加第三方的包(guice-3.0.jar和javax.inject.jar) 鏈接:http://pan.b ...


Google-Guice入門介紹(較為清晰的說明瞭流程):
http://blog.csdn.net/derekjiang/article/details/7231490 


 

使用Guice,需要添加第三方的包(guice-3.0.jar和javax.inject.jar)

鏈接:http://pan.baidu.com/s/1nuMjYOT 密碼:1soo

將包導入MyEclipse或eclipse的方法:http://jingyan.baidu.com/article/6079ad0e7e4de128fe86db40.html 


Google Guice 是一個輕量級的依賴註入框架。
Guice是由Google大牛Bob lee開發的一款絕對輕量級的java IoC容器。其優勢在於:
1. 速度快,號稱比spring快100倍。
2. 無外部配置(如需要使用外部可以可以選用Guice的擴展包),完全基於annotation特性,支持重構,代碼靜態檢查。
3. 簡單,快速,基本沒有學習成本。
Guice更適合與嵌入式或者高性能但項目簡單方案,如OSGI容器,spring更適合大型項目組織。
(作為一個初學者對於上述兩點沒有太多的體會,所以此方面沒有獨特而詳細的見解,我也是抱著學習的心態在接觸這些東西。)


 

註入方式:構造、屬性以及函數註入,guice的實現只要在構造函數,欄位,或者註入函數上標註@Inject
(此部分完整學習網址:http://www.cnblogs.com/whitewolf/p/4185908.html )


構造註入

public class ServiceImpl implements Service {
  private PeopleService people;
  private GoodsService goods;

  @Inject
  public ServiceImpl(PeopleService people, GoodsService goods) {
    this.people = people;
    this.goods = goods;
  }
}

屬性註入

public class ServiceImpl implements Service {
  private PeopleService people;
  private GoodsService goods;

  @Inject
  public init(PeopleService people, GoodsService goods) {
    this.people = people;
    this.goods = goods;
  }
}

函數註入

public public class ServiceImpl implements Service {
  private PeopleService people;
  private GoodsService goods;

  @Inject
  public setPeopleService(PeopleService people) {
    this.people = people;
  }

  @Inject
  public setGoodsService(GoodsService goods) {
    this.goods = goods;
  }
}

 

Module依賴註冊
Guice提供依賴配置類,需要繼承至AbstractModule,實現configure方法。在configure方法中我們可以用Binder配置依賴。
Binder利用鏈式形成一套獨具語義的DSL,如:
• 基本配置:binder.bind(serviceClass).to(implClass).in(Scopes.[SINGLETON | NO_SCOPE]);
• 無base類、介面配置:binder.bind(implClass).in(Scopes.[SINGLETON | NO_SCOPE]);
• service實例配置:binder.bind(serviceClass).toInstance(servieInstance).in(Scopes.[SINGLETON | NO_SCOPE]);
• 多個實例按名註入:binder.bind(serviceClass).annotatedWith(Names.named(“name”)).to(implClass).in(Scopes.[SINGLETON | NO_SCOPE]);
• 運行時註入:利用@Provides標註註入方法,相當於spring的@Bean。
• @ImplementedBy:或者在實現介面之上標註@ImplementedBy指定其實現類。這種方式有點反OO設計,抽象不該知道其實現類。
對於上面的配置在註入的方式僅僅需要@Inject標註,但對於按名註入需要在參數前邊加入@Named標註,如下


public void configure() {
  final Binder binder = binder();

  binder.bind(NamedService.class).annotatedWith(Names.named("impl1")).to(NamedServiceImpl1.class);
  binder.bind(NamedService.class).annotatedWith(Names.named("impl2")).to(NamedServiceImpl2.class);
}

@Inject
public List<NamedService> getAllItemServices(@Named("impl1") NamedService nameService1,
@Named("impl2") NamedService nameService2) {
}

Guice也可以利用@Provides標註註入方法來運行時註入:如


@Provides
public List<NamedService> getAllItemServices(@Named("impl1") NamedService nameService1,
@Named("impl2") NamedService nameService2) {
final ArrayList<NamedService> list = new ArrayList<NamedService>();
list.add(nameService1);
list.add(nameService2);
return list;
}

 

Google Guice 系列教程 - 基礎實踐

原文:http://www.cnblogs.com/youngC/archive/2012/12/21/2828419.html?utm_source=tuicool&utm_medium=referral 

(本部分均轉自上面的網址,詳看原文)


 

Google Guice 是一個輕量級的依賴註入框架,它支持Java 5或者更高版本的JDK,得利於Java 5中提供的泛型 (Generics) 和註釋 (Annotations) ,它可以使得代碼類型安全 (type-safe) 。那麼何時使用在代碼中使用 Guice 進行註入呢?一般來說,如果在你的應用代碼中業務對象 (Business Objects) 之間的關係或者依賴需要手動維護的話,你就可以使用Guice 進行註入。

該文章中,首先我將通過一些例子來初步的認識一下 Guice 框架,然後我將介紹下 依賴註入框架的理論知識 以及在應用程式中使用依賴註入的好處,同樣我也會和大家探討一下 Guice 提供的用於簡化代碼的 API (包括Annotations) 。最後通過大量使用 Guice API的例子來使大家更好地理解這些API。

依賴註入(Dependency Injection)


由於Gucie 是一個依賴註入框架 (Dependency Injection Framework) ,因此我們首先要很清楚依賴註入 (Dependency Injection) 是什麼概念。這些年來,依賴註入變得越來越流行,變得越來越重要,在很多典型的應用中它甚至變成了一個必需的機制,比如 J2EE 5.0, Spring, JBoss Seam就是使用依賴註入的很好的例子。現在我們來使用一個簡單的例子來說明使用依賴註入框架的必要性。

請看以下代碼:


 

public interface Storage {
    public void store(String uniqueId, Data data);

    public Data retrieve(String uniqueId);
}

上面的介面 Storage 提供了存儲 (store) 和獲取 (retrieve) 數據的機制,由於數據可以存儲在資料庫中也可以存儲在一個文件中,因此上面介面 Storage 的實現可以如下。

public class FileStorage implements Storage {

    @Override
    public void store(String uniqueId, Data data) {
        // Store the object in a file using Java Serialization mechanism.
    }

    @Override
    public Data retrieve(String uniqueId) {
        // Code to retrieve the object.
 } 
}

實現類 FileStorage 可以將數據存儲到硬碟文件中,同樣也可以從硬碟文件中獲取存儲數據。接下來是 Storage 介面的另一種實現,它用於將數據存儲到資料庫中。

public class DatabaseStorage implements Storage {

    @Override
    public void store(String uniqueId, Data data) {
        // Open a connection and store the data.

    }

    @Override
    public Data retrieve(String uniqueId) {
        // Get the data from the Database.
    }
}

現在,我們來看一個 Storage 應用客戶端的例子。下麵的 StorageClient 代碼片段中,首先初始化一個 FileSorage,然後在轉向 DatabaseStorage 實現。(new Data()報錯,所以我註釋掉了)

public class StorageClient {

    /**
     * @param one-bird
     */
    public static void main(String[] args) {
        //Making use of the File
        Storage storage=new FileStorage();
        //storage.store("123", new Data());
        
        // Making use of the database.
        storage = new DatabaseStorage();
        //storage.store("456", new Data());
    }

}

仔細看下 StorageClient 模塊中的代碼,儘管介面 (Storage) 和實現類 (FileStorage/DatabaseStorage) 松耦合,但是 客戶端 (StorageClient) 模塊需要手動地去創建實現類的實例對象 (instance) ,同樣介面和實現類之間的關係 (Relationship) 是直接在客戶端代碼中寫死的,然而在大多數情況下,在代碼編譯的時候,客戶端應用程式已經知道需要綁定哪一種介面實現類,如果只綁定某一個具體的實現類,肯定比上面的代碼中同時實現兩個類 (某一個是沒必要的) 更有用。Google Guice 就是乾這個工作的,它在應用程式的客戶端代碼中創建不同形式服務 (Services) 實例, 而且客戶端和服務之間的依賴是通過一些簡單的配置機制 (Configuration Mechanism) 自動註入的。

接下來我將提供一個簡單使用 Guice Framework 的例子。

一個簡單的 Guice 例子


在這個簡單的例子中,讓我們看一下 Guice 在維護不同對象之間的關係/依賴時如何簡化開發的。讓我們看一下下麵的代碼片段,我們創建了一個 Add 介面,並且在裡面定義了一個 add() 方法。


 

public interface Add {
    public int add(int a, int b);
}

下麵是介面 Add 的一個實現類

public class SimpleAdd implements Add {

    @Override
    public int add(int a, int b) {
        return a + b;
    }
}

接著我們定義一個 Module 類,這個類用於使用 Guice API 在一個應用程式中創建 Bindings。Module 和 Bindings 理論方面的詳細介紹在後面章節。現在,你只需要明白通過 Binder 類,你可以將一些 Bindings 配置到某個 Module中。在 Guice 條目中,Binding 提供了一種方式將介面 (interface) 和實現類相關聯。

import com.google.inject.Binder;
import com.google.inject.Module;

public class AddModule implements Module {

    @Override
    public void configure(Binder binder) {
        binder.bind(Add.class).to(SimpleAdd.class);
    }
}

在上面的代碼中,我們告訴 Guice 將 SimpleAdd 實現類綁定到 Add 介面上,也就是說在客戶端調用Add.add() 方法時,實際會去執行 SimpleAdd.add() 方法。下麵給出了一個客戶端例子用戶使用 Add 介面。

import com.google.inject.Guice;
import com.google.inject.Injector;

public class AddClient {

    /**
     * @param one-bird
     */
    public static void main(String[] args) {
        Injector injector=Guice.createInjector(new AddModule());
        Add add=injector.getInstance(Add.class);
        System.out.println(add.add(2016, 1119));
    }

}

運行結果:

更多關於 Injector, Guice 的理論知識將會在後面的章節介紹。injector.getInstance(Add.class) 將會創建並返回一個 SimpleAdd 類型的實例。實際上是通過 AddModule.configure() 方法來獲取具體的綁定信息的。

Guice API 探討


 讓我們探討一下實現 Guice 依賴註入不同的 API。特別會涉及以下的 介面/實現類。

  • Binder
  • Injector
  • Module
  • Guice

1.Binder

Binder 介面主要是由與 Bindings 相關的信息組成的。一個 Binding 其實就是一個介面和其相應的實現類的映射關係。例如,回想一下上面的例子,我們創建了一個由介面 Add 指向 實現類 SimpleAdd 的映射關係。

從程式角度來說,可以通過以下代碼方式實現。註意的是無論是介面 (interface) 還是實現類 (implementation classes),都是通過 bind() 和 to()方法實現映射的。

binder.bind(Add.class).to(SimpleAdd.class)

同樣也可以將一個介面直接映射到一個具體的實例對象,代碼如下。

binder.bind(Add.class).to(new SimpleAdd())

第三種方式是將一個介面綁定到一個相應的 Provider 類。預設情況下,Guice 框架會創建並返回應用程式需要的實例對象。但是,如果需要定製化一個對象創建流程(Object Creation Process),該怎麼辦? Providers 可以很簡單的實現這種定製化。 你只需要遵循傳統的工廠模式(Factory Pattern)創建對象的方式使用 Providers,例如下麵的代碼。

binder.bind(Add.class).to(new AddProvider<Add>())

後面我將會通過一些例子講解如何創建 Provider 對象。不過現在,你只需要知道在 AddProvider 類中提供了一種工廠方法,它會返回具體的 Add 實現類的實例對象。後面我同樣會講解到如何將一個介面綁定到多個具體實現上。

2. Injector

Injectors 通常會在客戶端 (Clients) 使用,它只關心如何創建 (Creating)和維護 (Maintaining) 對象(生命周期)。Injectors 會去維護一組預設的 Bindings (Default Bindings),這裡我們可以獲取創建和維護不同對象間關係的配置信息 (Configuration information)。以下代碼將會返回 Add 的實現類對象。

Add addObject = injector.getInstance(Add.class)

你可以簡單地通過 Injector.getBindings() 方法獲取與 Injector 相關的 Bindings信息,getBindings() 方法會返回一個 Map。

Map<Key, Binding> allBindings = injector.getBindings()

這裡需要註意的是每一個 Binding 通常有一個對應的 Key 對象,該對象是由 Guice 自動創建並維護的。如果你想要獲取於Injector相關的 Providers 的話,你可以通過以下方法獲取。

Provider<SomeType> provider = injector.getProvider(SomeType.class)

3. Module

Module 對象會去維護一組 Bindings。在一個應用中可以有多個 Module  。反過來 Injectors 會通過 Module 來獲取可能的 Bindings。Module 是通過一個包含需要被重寫 override 的 Module.configure() 方法的介面去管理 Bindings。 簡單地說,就是你要繼承一個叫做 AbstractModule的類,這個類實現了 Module 介面,並且重寫 configure() 方法, 代碼如下。

class MyModule extends AbstractModule{
 
    public void configure(Binder binder){
 
        // Code that binds information using the various
        // flavours of bind method.
    }
}

4. Guice

客戶端 (Clients) 是通過 Guice 類直接和其他 Objects 進行交互的。Injector 和不同的 Modules 之間的聯繫是通過 Guice 建立的。例如下麵的代碼。

MyModule module = new MyModule();
Injector injector = Guice.createInjector(module);

這裡需要註意的是 Guice.createInjector() ,該方法接受一個 Module 對象作為參數。 Module 類必需要重寫 configure() 方法, 該方法是用於傳遞一個 預設 Binder 對象, 該 Binder 對象為應用程式用於填充特定的 Bindings (to Classes, Objects and Providers)。 當客戶端調用 Injector 類的 getInstance() 方法創建一個實例的時候,Injector 會從 Binder 對象維護的各種 Bindings 中獲取原來的對象。

Guice 註釋 (Annotations)


Guice 提供了一些十分有用的 Annotations ,這些 Annotations 可以用來在應用程式中添加 元數據 (meta-data)。 這一章節我將要講以下幾個註釋。

  • Implemented By
  • Inject
  • Provided By
  • Singleton

1. Implemented By

該 Annotation 用於指向介面的實現類。例如,如果 Add 介面有多個實現類,但是我們希望 SimpleAdd 是 Add 的預設實現類,於是我們可以像下麵一樣處理。

@ImplementedBy(SimpleAdd.class)
interface Add{
 
    public int add(int a, int b);
 
}

2. Inject

我們可以使用 Inject Annotation 來直接將實例註入到客戶端的代碼中。該註釋可以用於某個類的構造方法上,代碼如下。

class Client{
 
    @Inject
    public Client(MyService service){
    }
}

上面的代碼,我們是基於構造方法層次 (Constrcctor-level)的 註入,並且假設 MyService 介面的具體實現已經在應用程式的 Module 中定義映射好了。同樣你也可以在方法層次 (Method-level) 和 欄位層次 (Field-level) 使用註釋。

3. Provided By

假設我們想要為一些介面定製化對象創建的流程 (Object creation process),那麼我們需要依賴 Guice Provider 機制, 對於介面 Add 來說,我們需要使用 AddProvider 來創建並返回 SimpleAdd 對象。在這個案例中,我們可以直接在介面聲明處使用 ProvidedBy 註釋來指定該介面的 Provider 類型, 代碼如下。

@ProvidedBy(AddProvider.class)
public interface Add{
 }

4. Singleton

預設情況下,客戶端可以多次使用 Injector.getInstance() 來調用對象,每一個都會返回一個新創建的對象。如果我們想要使用單例模式(Singleton Pattern)來獲取對象,即 One Instance in the application,你可以在實現類上使用 Singleton 註釋去標記。

@Singleton
public class MyConnection{
 
    public void connect(){
    }
 
    public void disconnect(){
    }
}

例子 (Samples)


 

這一章節將會提過更多的例子幫助你理解和使用 Guice API ,我將會更加詳細的解析。

1. 簡單的例子

在這個簡單的例子中我們沒有使用介面編程,即將介面和實現分離。我們只有一個實現類 Player 和一個依賴它的客戶端 PlayerTest, 這裡 Guice 沒有做什麼,只是提供了一個映射。

首先來看一下 Player 類。

public class Player {
    public String name;

    public Player() {
    }

    public String toString() {
        return name;
    }
}

下麵是客戶端代碼的例子,用於使用 Player 類。這裡需要註意的是我們沒有在 Guice.createInjector() 方法裡面傳遞 Module ,因為我們不需要在程式代碼中綁定對象。

import com.google.inject.Guice;
import com.google.inject.Injector;

public class PlayerTest {

    /**
     * @param one-bird
     */
    public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        Player player = injector.getInstance(Player.class);
        player.name = "live";
        System.out.println(player);
    }
}

2. 處理多個依賴 (Multiple Dependencies)

這一小節裡面,我們將探討如何使用 @Inject 註釋來處理多個依賴。 比方說有一個對象直接依賴其它兩個或者多個對象。這裡我們創建一個簡單的 Case ,一個人有一臺筆記和一個手機。

首先我們給出 Mobile 類和 Laptop 類。

public class Laptop {
    private String model;
    private String price;

    public Laptop() {
        this.model = "HP 20161119";
        this.price = "$1119";
    }

    public String toString() {
        return "[Laptop: " + model + "," + price + "]";
    }
}
public class Mobile {
    private String number;

    public Mobile() {
        this.number = "20161114";
    }

    public String toString() {
        return "[Mobile: " + number + "]";
    }
}

接下來我們將會在 Person 類中使用 @Inject 註釋來直接引用 Laptop 和 Mobile 對象。註意我們這兒使用的是構造方法層次上的註入。

import com.google.inject.Inject;

public class Person {
    private Mobile mobile;
    private Laptop laptop;

    @Inject
    public Person(Mobile mobile, Laptop laptop) {
        this.mobile = mobile;
        this.laptop = laptop;
    }

    public void displayInfo() {
        System.out.println("Mobile:" + mobile);
        System.out.println("Laptop:" + laptop);
    }
}

最後是客戶端的代碼,這段代碼用於使用這個例子。由於我們沒有使用到 Bindings, 我們沒有在 Guice.createInject() 方法中傳遞 Module 對象。

import com.google.inject.Guice;
import com.google.inject.Injector;

public class MultipleDependencyTest {

    /**
     * @param one-bird
     */
    public static void main(String[] args) {
        Injector injector=Guice.createInjector();
        Person person=injector.getInstance(Person.class);
        person.displayInfo();
    }

}

運行結果:

3. 使用 Binding 註釋

在 Guice 中,一個類型不能綁定多個實現,如下,代碼會拋 Runtime Error.

binderObject.bind(SomeType.class).to(ImplemenationOne.class);
binderObject.bind(SomeType.class).to(ImplemenationTwo.class);

由於 Guice 並不知道客戶端究竟要綁定哪一個實現類,因此拋出了異常。但是在類似 Java 的語言中,一個類可以實現多個介面,基於這個思想,Guice 提供了一種依賴 Binding 註釋的方式來實現一個類型綁定多個實現。例如,介面 Player 定義如下,

public interface Player {
    public void bat();

    public void bowl();
}

接著我們提供了 Player 的兩種實現類, GoodPlayer 和 BadPlayer。

public class GoodPlayer implements Player {

    @Override
    public void bat() {
        System.out.println("I can hit any ball");
    }

    @Override
    public void bowl() {
        System.out.println("I can also bowl");
    }

}
public class BadPlayer implements Player {

    @Override
    public void bat() {
        System.out.println("I think i can face the ball");
    }

    @Override
    public void bowl() {
        System.out.println("I don't know bowling");
    }

}

現在我們開始介紹 Guice ,對於介面 Player 而言,有兩個實現類 GoodPlayer 和 BadPlayer。無論如何,最終客戶端只會使用其中一個具體的實現類,無論它使用GoodPlayer 實現類還是 BadPlayer 實現類,通過一些註釋機制 (Annotaion mechanisms) 我們可以指示 Guice 使用不同的實現。代碼實現如下。

 1 import com.google.inject.Binder;
 2 import com.google.inject.Module;
 3 
 4 public class PlayerModule implements Module {
 5 
 6     @Override
 7     public void configure(Binder binder) {
 8         binder.bind(Player.class).annotatedWith(Good.class)
 9                 .to(GoodPlayer.class);
10         binder.bind(Player.class).annotatedWith(Bad.class).to(BadPlayer.class);
11     }
12 
13 }

註意第8行和第10行代碼,我們分別使用了.annotatedWith(Good.class) 和 .annotatedWith(Bad.class), 這兩處代碼指明瞭如果使用Good註釋,那麼就綁定GoodPlayer實現類,如果使用了Bad註釋,那麼就綁定BadPlayer實現類。

上面的代碼中我們使用了兩個自定義的 Annotation,Good 和 Bad。下麵我們給出 Good annotation 和 Bad annotation 的代碼。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.inject.BindingAnnotation;

@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
@Target(ElementType.LOCAL_VARIABLE)
public @interface Good {
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.inject.BindingAnnotation;

@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
@Target(ElementType.LOCAL_VARIABLE)
public @interface Bad {
}

接下來是上面程式的客戶端代碼。這裡需要註意的是當在客戶端代碼中請求某一個介面的具體實現的時候,可以直接通過指定不同的 Annotation 來指定返回不同的實現類。

 1 import com.google.inject.Injector;
 2 import com.google.inject.Module;
 3 
 4 public class PlayerClient {
 5 
 6     /**
 7      * @param one-bird
 8      */
 9     public static void main(String[] args) {
10         PlayerModule module = new PlayerModule();
11         Injector injector = Guice.createInjector(new Module[] { module });
12 
13         @Bad Player player = injector.getInstance(Player.class);
14         player.bat();
15         player.bowl();
16     }
17 
18 }

此處註意第11行和第13行。 第13行代碼 @Good 告訴 Guice 去 Playe Moduler 中獲取一個 GoodPlayer實例對象。

註意:報錯,我根據錯誤,修改了一些代碼,發現沒有完成。(希望其他學友指正)

批註:原文中這種方法說可以多個實現,我在測試時發現會報一個錯誤,所以想要瞭解的去看原文,因為有錯所以這裡提醒。

4. Named 註釋

像上面例子中,如果只是為了標記實現類以便於客戶端使用,而為每一個實現類創建新的 Annotation ,那麼是完全沒有必要的。我們可以使用 @Named 註釋來命名這些 entities。這兒有一個工具方法 - Names.named() ,當你給它一個命名,它會返回好一個命名好的 Annotation。例如上面的例子中,在 Player Module 中可以使用 Names.named() 來完成一些相同的事情。

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.name.Names;

public class PlayerModule implements Module {

    @Override
    public void configure(Binder binder) {
        binder.bind(Player.class).annotatedWith(Names.named("Good"))
                .to(GoodPlayer.class);
        binder.bind(Player.class).annotatedWith(Names.named("Bad"))
                .to(BadPlayer.class);
    }

}

現在在客戶端代碼中,我們將使用 @Named() annotation來獲取註釋。

@Named("Good") Player goodPlayer = (Player)injector.getInstance(Player.class);
 
@Named("Bad") Player badPlayer = (Player)injector.getInstance(Player.class);

註意:這裡也報錯   

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The annotation @Named is disallowed for this location

5. 一個簡單的 Provider

在 Guice 中 Providers 就像 Factories 一樣創建和返回對象。在大部分情況下,客戶端可以直接依賴 Guice 框架來為服務(Services)創建依賴的對象。但是少數情況下,應用程式代碼需要為一個特定的類型定製對象創建流程(Object creation process),這樣可以控制對象創建的數量,提供緩存(Cache)機制等,這樣的話我們就要依賴 Guice 的 Provider 類。

例如,我們需要為 MockConnection 創建一個對象創建和銷毀的流程,代碼如下。

public class MockConnection {
    public void connect() {
        System.out.println("Connecting to the mock database");
    }

    public void disConnect() {
        System.out.println("Dis-connecting from the mock database");
    }
}

現在我們來寫一個簡單的 Provider 類來實現 Guice 的 Provider 介面,使用它創建並返 MockConnection對象,代碼如下。

import com.google.inject.Provider;

public class ConnectionProvider implements Provider<MockConnection> {
    @Override
    public MockConnection get() {
        // Do some customization mechanism here.
        MockConnection connection = new MockConnection();
        // Do some customization mechanism here too.
        return connection;
    }
}

需要註意的是,所有的自定義 Provider 類必需實現 Provider 介面,並且重寫裡面的 get() 方法。現在 Module 需要留意這個自定義的 Provider 類,它需要請求 ConnectionProvider 來創建對象,而不是直接創建對象,實現的代碼如下。

 1 import com.google.inject.Binder;
 2 import com.google.inject.Guice;
 3 import com.google.inject.Injector;
 4 import com.google.inject.Module;
 5 
 6 public class ConnectionTest {
 7 
 8     /**
 9      * @param one-bird
10      */
11     public static void main(String[] args) {
12         Injector injector = Guice.createInjector(new Module() {
13 
14             @Override
15             public void configure(Binder binder) {
16                 binder.bind(MockConnection.class).toProvider(
17                         ConnectionProvider.class);
18             }
19         });
20         
21         MockConnection connection=injector.getInstance(MockConnection.class);
22         connection.connect();
23         connection.disConnect();
24     }
25 
26 }

運行結果:

註意第16行,我們使用 toProvider() 方法將 MockConnection.class 綁定到一個 Provider 上。

小結


這篇文章簡要的講解了一些 Guice 相關的內容,有時間我將講講Guice的一些高級應用,還有 Robo Guice的使用。
本文參考鏈接

http://code.google.com/p/google-guice/

http://www.javabeat.net/2007/08/introduction-to-google-guice/

 

/**********************************************************
 * Author: Canice Hu
 * QQ    : 540678976
 * 版權歸本人所有,轉載請聲明出處
 **********************************************************/


 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第一步:在資料庫創建一個存放賬號密碼的表單 第二步:創建一個登入項目 拆分成三層: CS層: BLL層: DAL層: Common層: Web.config: ...
  • 最近在做一個項目,需要用到等待窗體,在DevExpress下麵有SplashScreen控制項可以使用,同時也有ProgressIndicator控制項能用,但是如果沒有用Dev開發的話,我們就需要自定義一個等待窗體了。 首先,把截圖放上來: 實現的功能比較簡單,就是在程式處理 一些耗時比較多的代碼時, ...
  • 前幾篇講完查詢框和工具欄,這節講表格數據相關的操作,詳情如下: ...
  • SQL跟蹤如下: 建議加一個 go 語句解決問題,如下圖 ...
  • 本文實例展示了DevExpress實現為TextEdit設置水印文字的方法,是一個很實用的技巧。分享給大家供大家參考。 轉自 http://blog.csdn.net/yh0503/article/details/51487726 關鍵代碼如下: 1 public static void SetWa ...
  • ASP.NET MVC 基礎入門 http://www.cnblogs.com/liunlls/p/aspnetmvc_gettingstarted.html 設置預設啟動頁面 設置重定向配置(沒有登錄的匿名用戶將重定向到配置的地址) 設置控制器過濾器; 特性也可以只設置方法;下麵的代碼中,如果用戶 ...
  • 這個配置節甚是簡單,在MSDN中的介紹也甚是簡單:為 ASP.NET 應用程式配置頁的視圖狀態設置。 historySize的作用是設置要存儲在頁歷史記錄中的項數。 但是這根本是看不明白他是幹嘛的,百度上一大串都是單純說說配置節的意思,根本沒再進一步闡述他的作用,我就不信其他人都懂了。還好有谷歌。看 ...
  • 概述 該示例(TODO MVP)是後續各種示例演變的基礎,它主要演示了在不帶架構性框架的情況下實現M V P模式。其採用手動依賴註入的方式來提供本地數據源和遠程數據源倉庫。非同步任務通過回調處理。 註意:MVP中View的概念是有所不同的: android.view.View類我們叫它 "Androi ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...