Guice是Google的一个轻量级的依赖注入框架,使用这个框架可以很容易的实现模块间的依赖注入,有效提高模块之间的解耦和程度,使模块之间的交互更灵活、更容易维护。
下面先来看一下Guice的运行机制:

然后通过一个非常简单的例子来说明Guice的使用:
首先,建立一个接口,这个接口的实现就是需要被注入的服务:
1 public interface Im {
2 public void say(String s);
3 public boolean connect();
4 public boolean disconnect();
5 }
然后,我们编写来个实现该接口的具体实现:
实现1,ImImpl:
01 public class ImImpl implements Im {
02 @Override
03 public boolean connect() {
04 System.out.println("ImImpl connected!");
05 return true;
06 }
07
08 @Override
09 public boolean disconnect() {
10 System.out.println("ImImpl disconnected!");
11 return true;
12 }
13
14 @Override
15 public void say(String s) {
16 System.out.println("ImImpl say:"+s);
17 }
18 }
实现2,ImMock:
01 public class ImMock implements Im {
02
03 @Override
04 public boolean connect() {
05 System.out.println("ImMock connected!");
06 return true;
07 }
08
09 @Override
10 public boolean disconnect() {
11 System.out.println("ImMock disconnected!");
12 return true;
13 }
14
15 @Override
16 public void say(String s) {
17 System.out.println("ImMock say:"+s);
18 }
19 }
接下来,我们编写一个依赖于Im接口的类,MyIm:
01 import com.google.inject.Inject;
02 import edu.scut.emos.im.Im;
03
04 public class MyIm{
05
06 Im impl;
07
08 @Inject
09 public MyIm(Im impl){
10 this.impl = impl;
11 }
12
13 public void doit(String detail){
14 impl.connect();
15 impl.say(detail);
16 impl.disconnect();
17 }
18
19 }
在第8行处,我们使用了@Inject注解,该注解用来告诉Guice框架,这里是一个注入点。
接着,我们要编写一个配置模块,用来配置被注入的具体服务以及注入的目标:
01 import com.google.inject.Binder;
02 import com.google.inject.Module;
03 import com.google.inject.Scopes;
04 import edu.scut.emos.im.Im;
05 import edu.scut.emos.im.ImImpl;
06 import edu.scut.emos.im.ImMock;
07
08 public class MyModule implements Module {
09
10 Class<? extends Im> theClass = ImImpl.class;
11
12 public void setInstance(int i){
13 if(i>0){
14 theClass = ImImpl.class;
15 }else{
16 theClass = ImMock.class;
17 }
18 }
19
20 @Override
21 public void configure(Binder binder) {
22 binder.bind(Im.class).to(theClass).in(Scopes.SINGLETON);
23 }
24
25 }
该配置模块实现了Guice的Module接口,实现它的cofigure,根据之前给出的时序图,我们知道Guice就是通过这个方法来实现注入的,所以能通过重写这个方法来绑定输入的具体服务和注入点。第22行代码详细描述了这个情况:将Im接口(Im.class)和具体的实现(theClass)绑定,范围指定是Scopes.SINGLETON,也就是说,每一次注入都是使用最初生成的那个服务实体对象,而不用另外再新建一个实体对象来注入,除非我们改变了被注入的服务。
最后来一个演示程序:
01 import com.google.inject.Guice;
02 import com.google.inject.Injector;
03
04 public class Main {
05 public static void main(String[] args) {
06 MyModule module = new MyModule();
07 module.setInstance(1);
08 Injector inj = Guice.createInjector(module);
09 MyIm myIm = inj.getInstance(MyIm.class);
10 myIm.doit("test");
11
12 module.setInstance(0);
13 inj = Guice.createInjector(module);
14 myIm = inj.getInstance(MyIm.class);
15 myIm.doit("test");
16 }
17 }
程序的执行结果就是:
ImImpl connected!
ImImpl say:test
ImImpl disconnected!
ImMock connected!
ImMock say:test
ImMock disconnected!
前三行是由ImImpl输出的,后三行是由ImMock生成的,我们在程序的执行流程中,通过改变配置模块(myModule)的内容,通过Guice来为MyIm注入具体的Im实现,得到我们想要的MyIm对象。这就是Guice可以带给我们的最基本的注入功能,可以很方便很快捷地实现依赖注入,Guice还提供了很多的注入类型和配置选项,建议大家都去试试看。
Guice官方网站:http://code.google.com/p/google-guice/
最新评论