Guice与Spring框架的区别
文章作者 100test 发表时间 2007:05:07 15:53:57
来源 100Test.Com百考试题网
依赖注入,DI(Dependency Injection),它的作用自然不必多说,提及DI容器,例如spring,picoContainer,EJB容器等等,近日,google诞生了更轻巧的DI容器……Guice!
废话不多讲了,先看看Guice是如何实现注入的吧。
定义一个简单的service接口和它的实现吧:
public interface MyService ...{
void myMethod().
}
public class MyServiceImpl implements MyService ...{
public void myMethod() ...{
System.out.println("Hello,World!").
}
}
以上是最普通的接口和其实现,没什么可说的。
定义一个测试类,这个类里边包括service对象的一个引用,这个对象是需要Guice进行注入的
import com.google.inject.Inject.
public class Client ...{
MyService service.
@Inject //告诉容器,这里的service对象的引用,需要进行注入
void setService(MyService service) ...{ //这里的方法名字可以任意定义
this.service = service.
}
public void myMethod() ...{
service.myMethod().
}
}
这里除了加了一个@Inject,和Spring的配置没有任何的区别,@Inject,是表示对容器说,这里的service需要注射,等到运行的时候,容器会拿来一个实例给service,完成注射的过程。
定义Guice的Module文件 告诉容器如何进行注入
import com.google.inject.Binder.
import com.google.inject.Module.
import com.google.inject.Scopes.
public class MyModule implements Module ...{
public void configure(Binder binder) ...{ binder.bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON).
// 这句代码的意思是说:运行时动态的将MyServiceImpl对象赋给MyService定义的对象,而且这个对象是单例的。
}
}
创建测试类
import com.google.inject.Guice.
import com.google.inject.Injector.
public class Test ...{
public static void main(String[] args) ...{
MyModule module = new MyModule().// 定义注射规则
Injector injector = Guice.createInjector(module).// 根据注射规则,生成注射者
Client client = new Client().
injector.injectMembers(client).// 注射者将需要注射的bean,按照规则,把client这个客户端进行注射
client.myMethod().
}
}
运行测试类,控制台输出:Hello,World!
完成注入过程
下面看看Guice还有哪些其它的使用特性。
1,如果在实现你确定MyService定义的对象,就要被注射为MyServiceImpl而不是其它的实现类的话,可以在MyService接口加上@ImplementedBy(MyServiceImpl.class)
import com.google.inject.ImplementedBy.
@ImplementedBy(MyServiceImpl.class)
//我总觉得这样有点背离了依赖注入的初衷了.
public interface MyService ...{
void myMethod().
}
这样的话,在MyModule里的configure方法中就可以不加任何东西,容器就会自动注射给MyServiceImpl对象。
2,可以对Field进行注解式注入
在Client.java中也可以把这个@Inject标注在MyService service.的前边,如:@Inject MyService service.
3,可使用自定义Annotation标注。
package mypackage.
import java.lang.annotation.ElementType.
import java.lang.annotation.Retention.
import java.lang.annotation.RetentionPolicy.
import java.lang.annotation.Target.
import com.google.inject.BindingAnnotation.
@Retention(RetentionPolicy.RUNTIME)
@Target( ...{ ElementType.FIELD, ElementType.PARAMETER })
@BindingAnnotation
public @interface MyInterface ...{
}
那么Client.java需要改为
package mypackage.
import com.google.inject.Inject.
public class Client ...{
@Inject @MyInterface MyService service.
void setService(MyService service) ...{ // 这里的方法名字可以任意定义
this.service = service.
}
public void myMethod() ...{
service.myMethod().
}
}
MyModule.java中的configure方法内容需改为:
binder.bind(MyService.class).annotatedWith(MyInterface.class).to(
MyServiceImpl.class).in(Scopes.SINGLETON).
意思是说对于标注为MyInterface的MyService定义的对象进行注入
进行Annotation标注的成员(Field,method,argument等)进行自定义Annotation标注,该成员既拥有该属性,可以在运行,根据这些成员的不同属性,做一些不同的事情. 例如:spring的AspectJ,xdoclet等都是如此。