Google Guice 学习笔记(1) Hello Guice

最近看了一点Dependency Injection的东西, 发现很难理解为什么要使用DI, 为什么要IoC, 到底能带来什么好处. 于是决定选择一款框架学习一下, 以增进自己的理解. 比较之后, 选择了Google Guice, 主要还是从如何使用入手.


1. Guice简介

Guice是Google开发的一款轻量级的注入框架(a lightweight dependency injection framework for Java 5 and above), 与大名鼎鼎的Spring相比, 确实是轻量级的框架. 其主要目标是替代开发中使用关键字new或者大量使用的工厂方法, 以达到解除耦合的目的; 同样该框架的作者Bob Lee也希望Guice能给使用者带来更好的体验, 能帮助开发者提高开发速度和方便维护. OK, 废话不多说了. 详细的介绍可以去官网查看: http://code.google.com/p/google-guice/


2. Hello Guice

我使用的参考书为Apress的Google Guice(Agile Lightweight Dependency Injection Framework), 是Google官网Slice的推荐用书. 该书使用了一个FortuneCookie的例子, 非常形象的介绍了Guice的使用方法. 在本文, 参考介绍使用贩卖Juice的VendingMachine作为例子.


在科技发展初期, 一切都是那么简单.

我们有一个只贩卖一种果汁的自动贩卖机. 为此我们提供了一个接口, 因为世界上不止这么简单的一种贩售机, 除了果汁, 还能卖点别的东西. 而自动贩卖机的果汁也很简单, 只包含一个价格的属性, 当然果汁的味道还是不错的.

public interface VendingMachine {
    public int showPrice();
    public Juice sellJuice();
}

import java.util.Arrays;
import java.util.List;

public class VendingMachineImpl implements VendingMachine {
	
	private static final List KINDS_OF_JUICE =
		Arrays.asList(
			new Juice(100)
		);
	@Override
	public int showPrice() {
		return KINDS_OF_JUICE.get(0).getPrice();
	}
	@Override
	public Juice sellJuice() {
		return KINDS_OF_JUICE.get(0);
	}
}

public class Juice {
	private int price;
	public Juice(int price) {
		this.price = price;
	}
	public int getPrice() {
		return price;
	}
	public String toString() {
		return "It tastes good!";
	}
}



那么作为消费者Consumer, 可以询问价格并且购买果汁. 当然购买果汁需要自动贩售机提供服务.

import com.google.inject.Inject;

public class Consumer {
	private VendingMachine vendingMachine;
	
	@Inject
	public Consumer(VendingMachine vendingMachine) {
		this.vendingMachine = vendingMachine;
	}
	public int getPrice() {
		return vendingMachine.showPrice();
	}	
	public Juice buyJuice() {
		return vendingMachine.sellJuice();
	}
}


在构造函数上我们添加了一个@Inject的标记, 这个是Guice的标记, 表示在构造函数进行Inject, 再加上Module, 我们就可以把VendingMachine和VendingMachineImpl粘合起来. Module是Guice提供的一个接口, 是其指定实现方式的一种方法, 也是比较推荐的一种方式. 绑定的语法可以这么来读: 绑定VendingMachine到VendingMachineImpl的实现上, 使用单例模式. 在Module中进行绑定后, 在标记为@Inject的地方, Guice就会自动为其指定一个实现的实例.

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

public class VendingMachineModule implements Module {

	@Override
	public void configure(Binder binder) {
		binder.bind(VendingMachine.class)
			  .to(VendingMachineImpl.class)
			  .in(Scopes.SINGLETON);
	}

}

 

万事俱备, 只欠东风. 接下来该喝点果汁了. 通过Guice.createInjector使用我们的Module定义创建出一个Injector后, 我们就可以通过getInstance方法来获取各种对象, 从此告别new和工厂方法. 

 

public class Bootstrap {
	public static void main(String[] args) {
		Injector injector = Guice.createInjector(new VendingMachineModule());
		Consumer consumer = injector.getInstance(Consumer.class);
		System.out.println("The price of juice is " + consumer.getPrice());
		System.out.println("So, buy this juice and drink it: " + consumer.buyJuice());
	}
}
 

以上为第一个Guice的例子, 我们可以简单的总结出最基本的使用方法: 通过Module配置抽象与实现的关系, 通过@Inject标签来标记注入点. 然后使用万能的Injector来获得对象. 应该是一个很明确的思路, 使用起来也比较简洁.

但是问题随之而来:

1. 这样做能为我们带来什么好处呢? 

2. 这就是传说中的Dependency Injection, 该如何去解释. 

3. 我们如何能提供更多的服务(More Juice).

4. 我们还有一台售卖零食的自动贩卖机, 我们如何能在买到果汁之后, 再去购买些零食呢? 

 

后面的学习将继续对Guice框架的细节进行学习, 并围绕以上问题来做一些思考.

 

 

 

 

你可能感兴趣的:(spring,框架,Google,IOC)