初次认识Guice

上一篇 / 下一篇  2008-03-19 14:56:20 / 个人分类:Guice

从网站上看到了有人提起这个框架——Guice,google名下的产物——一个彼Spring快的DI容器,兴趣使然,马上到http://code.google.com/p/google-guice/上去看了看,发现居然是Bob Lee这位大仙的杰作,还犹豫什么,download下来试试!

      恩,从哪里试起呢?还是老规矩,碰到新的东西就来验证我们经典的例子——Hello World!

      这个东西说是DI,居然没有.xml或者.properties文件,老天它用的是该死的Annotation,很好,要是大家也想尝试的话统统5.0或者以上的干活。安装好环境,开始动手!可是从哪里开始呢?既然说是DI容器,那好,我们先把我们的程序准备好,然后再看它把各个需要的东西怎么Inject。

      借鉴一下Spring开发手册里的例子吧,稍微改改(无聊的人不要骂这个程序,因为它太简单,我都想骂!)。既然是要打印,我们先来一个打印的服务接口:

publicinterfacePrintService
{
    
publicvoidprint(String str);
}

很好,再来一个它的实现:

publicclassPrintServiceImplimplementsPrintService
{

    
publicvoidprint(String str)
     {
         System.out.print(str);
     }

}

然后呢?一个打印客户Client:

publicclassClient
{
    
privateString str="Hello world";
    
privatePrintService service;
    voidprintString()
     {
         service.print(str);
     }

}

看到了么?这次Inject的不是那个该死的字符串“Hello World”,而是该死的打印服务!好了,Client和我们的打印服务是分开的,我不知道Guice会怎么把打印服务在Client需要的时候Inject进来。不管怎么做,一个test是应该有的:

importjunit.framework.TestCase;

publicclasstestClientextendsTestCase
{

    
publicvoidtestPrintString()
     {
         Client client
=newClient();
         client.printString();
     }

}

好了,试试看,应该是红色的条子。废话,Client在这里根本不知道该死的打印服务在哪里。那么寻找打印服务就是Guice的事情了。

      让我们看看Guice是怎么进行Inject的。我们想要Client在使用的时候找到打印服务,那么我们应该在Client需要的时候将其Inject进去,这样的话我们需要写一个类似于setter的东西来建造一个Inject点,那么我们在Client里添加些东西:

import com.google.inject.Inject;
publicclassClient
{
    
privateString str="Hello world";
    
privatePrintService service;
     @Inject
    voidinjectPrintService(PrintService service)
     {
        
this.service=service;
     }

    
voidprintString()
     {
         service.print(str);
     }

}

我们写入了一个injectPrintService方法,这个方法可以充当Inject点,然后我们在这个方法上面来一个Annotation——@Inject”,这就是告诉Guice应该在哪里Inject我们需要的打印服务。

      好了,我们下面要做的就是把PrintService和我们的实现动态的绑定起来(接口编程,好主意)。在Guice里,我们需要实现一个叫做Module的接口,Guice将一个binder传递给你的Module,然后你的Module将接口和它的实现绑定起来。让我们来试一下:

importcom.google.inject.Binder;
importcom.google.inject.Module;

publicclassMyModuleimplementsModule
{

    
publicvoidconfigure(Binder binder)
     {
         binder.bind(PrintService.
class).to(PrintServiceImpl.class);
     }

}

在我们需要打印服务的时候,Guice会自动创建一个PrintServiceImpl的实例给我们。OK,接下来就是如何注入的问题了,我们需要在test中实现:

importjunit.framework.TestCase;
importcom.google.inject.*;

publicclasstestClientextendsTestCase
{

    
publicvoidtestPrintString()
     {
         MyModule mo
=newMyModule();
         Injector in
=Guice.createInjector(mo);
         Client client
=newClient();
         in.injectMembers(client);
         client.printString();
     }

}

完了!一个全新的Hello world将要被打印出来了。

      Guice的工作流程是这样的:

首先将自己创建的Module传给Guice.createInjector(),Guice会为你的Module创建一个binder,你的Module利用这个binder来实现各种绑定,然后在Guice会创建一个Injector出来,我们就可以利用这个Injector来Inject我们的服务了。

    Guice将DI这个概念完完全全的诠释了出来,使我们在编写的应用的时候不必去考虑具体的实现在哪里,Guice会为你动态的绑定并且Inject的。很好使的框架,很有意思,以后继续关注!!


TAG:

引用 删除 4457880   /   2009-05-21 18:52:21
看了下似乎不错 呵呵  学习下
引用 删除 chinuxman   /   2009-02-13 16:25:45
5
引用 删除 就不性这么牛   /   2008-11-20 16:20:50
靠,看你这个说法,无非是把以前在配置文件里面的Mapping关系通过一个Module的Class定义出来啊。这个放在配置文件里面有多大区别啊?
引用 删除 Guest   /   2008-06-14 20:46:12
5
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2009-07-05  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 45405
  • 日志数: 171
  • 影音数: 3
  • 建立时间: 2008-02-28
  • 更新时间: 2008-05-19

RSS订阅

Open Toolbar