假设大家都了解interface和实现类这些基础知识。
按照下面的步骤编写我们的第一个guice程序。
接口Service。
public interface Service { void hello(); }
实现接口的ServiceImpl。
public class ServiceImpl implements Service{ public void hello() { System.out.println("hello"); } }
有了接口和实现类,现在我们看看如何通过guice取得它们。
import com.google.inject.*; public class Main { public static void main(String[] args) { Service service = Guice.createInjector(new Module(){ public void configure(Binder binder) { binder.bind(Service.class).to(ServiceImpl.class); } }).getInstance(Service.class); service.hello(); } }
注意一下new Module() {}部分,创建一个匿名类继承Module接口,这个接口里的configure()方法把Service.class和ServiceImpl.class绑定在一起,以后谁需要Service.class的时候,guice就会自动生成一个ServiceImpl.class放到需要的地方。
看到了吗?拜java强类型所赐,Service.class和ServiceImpl.class会在编译期间先检测一遍,省得你把不相干的两个东西放到一起。
把刚刚配置的这个Module作为参数交给Guice.createInjector(),这个方法获得的Injector对象就是我们贴近guice的大门,不管需要什么都可以向它索取。getInstance(Service.class)会根据Module中的绑定返回ServiceImpl.class的一个实例,调用hello.service()或者做什么都可以啦。
例子:01-01。
懒惰是程序员最大的美德。有没有不用写Module也可以让guice将Service.class和ServiceImpl.class自动关联起来的方法?让Main.class就像下面这样。
import com.google.inject.*; public class Main { public static void main(String[] args) { Service service = Guice.createInjector().getInstance(Service.class); service.hello(); } }
不用去写Module手工绑定Service.class和ServiceImpl.class,也能正确获得ServiceImpl.class类型的实例。
可惜完全不配置也是不可能的,为了实现自动绑定的功能我们要在Service.class中添加注解。
import com.google.inject.*; @ImplementedBy(ServiceImpl.class) public interface Service { void hello(); }
@ImplementedBy,告诉guice在所有需要Service.class的地方都放上ServiceImpl.class的实例。
有了这个注解,guice生成的Injector就能根据它的配置去查找ServiceImpl.class了,但是guice-1.0里还有漏洞,如果ServiceImpl.class没有实现Service.class接口,编译期间也无法检测出来,从这点来看还是使用Module比较保险。
例子:01-02。
有人会说,你这样把接口与实现类的关系直接硬编码到Service.java中有什么意义?如果是像spring里一样写到xml中以后升级的时候不用编译类,直接修改xml再重新部署就好了。
那我就这样说,实际工作中有可能频繁修改Service的实现吗?就算修改了,我只要改一下Service.java中注解的指向再编译就可以了,既然都要重新部署,编译一下也无关大雅吧?再说总要进行测试的,有人敢直接替换实现类吗?
估计又有人说了,那既然接口和实现类完全绑定,那为什么还要这么麻烦定义一个接口呢?直接写成实现类不就好了?
第一,接口是为了进行契约式编程,我们为其他组提供的接口可以约束双方使用的方法入口和参数形式。
第二,使用接口也更容易实现测试。
当然,如果你不愿意用接口也好,直接使用类的话,我们不必写任何注解guice也能自动找到需要的类。
ServiceImpl.java
public class ServiceImpl { public void hello() { System.out.println("hello"); } }
Main.java
import com.google.inject.*; public class Main { public static void main(String[] args) { ServiceImpl service = Guice.createInjector().getInstance(ServiceImpl.class); service.hello(); } }
例子:01-03。