使用Guice玩依赖注入

四月 21st, 2009 | 239 次阅读
Tags: Java Guice Posted in Java 技术杂项 :-)说点什么吧

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

      下面先来看一下Guice的运行机制:

        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/

Relate Posts:// 相关文章

去北京出差»
«ORACLE收购SUN的几点感触

“使用Guice玩依赖注入” 共有3条留言

  1. HP On

    这几天GAE的datastore似乎不怎么稳定~

我要留言

7+3=