guice:Guice和Spring框架的区别

转自:http://www.crazycoder.cn/ :http:/www.crazycoder.cn/Java/Article47605.html


依赖注入DI(Dependency Injection)它作用自然不必多说提及DI容器例如
springpicoContainerEJB容器等等近日google诞生了更轻巧DI容器……Guice !

废话不多讲了先看看Guice 是如何实现注入吧

定义个简单service接口和它实现吧!

public erface MyService ...{
void myMethod;
}
public MyServiceImpl implements MyService ...{
public void myMethod ...{
.out.prln("HelloWorld!");
}
} 以上是最普通接口和其实现没什么可说

定义个测试类这个类里边包括service对象个引用这个对象是需要Guice 进行注入

import com.google.inject.Inject;
public Client ...{
MyService service;
@Inject //告诉容器这里service对象引用需要进行注入
void Service(MyService service) ...{ //这里思路方法名字可以任意定义
this.service = service;
}
public void myMethod ...{
service.myMethod;
}
} 这里除了加了个@Inject和Spring 配置没有任何区别@Inject是表示对容器说这里service需要注射等到运
行时候容器会拿来个例子给service完成注射过程

定义GuiceModule文件告诉容器如何进行注入

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Scopes;
public MyModule implements Module ...{
public void configure(Binder binder) ...{
binder.bind(MyService.).to(MyServiceImpl.).in(Scopes.SINGLETON);
// 这句代码意思是说:运行时动态将MyServiceImpl对象赋给MyService定义对象
而且这个对象是单例
}
} 创建测试类

import com.google.inject.Guice ;
import com.google.inject.Injector;
public Test ...{
public void (String args) ...{
MyModule module = MyModule;// 定义注射规则
Injector injector = Guice .createInjector(module);// 根据注射规则生成注射者
Client client = Client;
injector.injectMembers(client);// 注射者将需要注射bean按照规则把client这个客户端进行注射
client.myMethod;
}
} 运行测试类控制台输出:Hello,World!

完成注入过程

下面看看Guice 还有哪些其它使用特性

1,如果在实现你确定MyService定义对象就要被注射为MyServiceImpl而不是其它实现类话可以在
MyService接口加上@ImplementedBy(MyServiceImpl.)

import com.google.inject.ImplementedBy;
@ImplementedBy(MyServiceImpl.)
//我总觉得这样有点背离了依赖注入初衷了
public erface 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 @erface MyInterface ...{
} 那么Client.java需要改为:

package mypackage;
import com.google.inject.Inject;
public Client ...{
@Inject @MyInterface MyService service;
void Service(MyService service) ...{ // 这里思路方法名字可以任意定义
this.service = service;
}
public void myMethod ...{
service.myMethod;
}
} MyModule.java中configure思路方法内容需改为:

binder.bind(MyService.).annotatedWith(MyInterface.).to(
MyServiceImpl.).in(Scopes.SINGLETON); 意思是说对于标注为MyInterfaceMyService定义对象进行注入

进行Annotation标注成员(Field,method,argument等)进行自定义Annotation标注该成员既拥有该属性可
以在运行根据这些成员区别属性做些区别事情 例如:springAspectJxdoclet等都是如此

下边是我做了下对比:

GuiceSpring 对比

Spring Guice
使用XML 使用将类和类的间关系隔离到xml中由容器负责注入被对象因此叫做依赖注入 不使用xml,将类和类
的间关系隔离到Module中声名何处需要注入由容器根据Module里描述注入被对象
使用Annotation 使用

支持自定义Annotation标注对于相同接口定义对象引用为它们标注上区别自定义Annotation注释就可以
达到同个类里边同个接口引用注射给区别实现在Module里用标注做区分灵活性大大增加

使用Annotation也未必是好事范型等新特性也未必是好事目前大多服务器均不支持jdk1.5,wls要9以前才支
持而目前客户由于价格原因也很少选用wls9至少我们做过项目中都没有功能再强客户不需要何用
运行效率 装载spring 配置文件时需解析xml效率低getBean效率也不高不过使用环境不会涉及到getBean只有
生产环境时候会用到getBean,在装载spring 应用时候已经完成全部注射所以这个低效率问题不是问题 使用
Annotationcglib, 效率高和spring 最明显个区别spring 是在装载spring 配置文件时候把该注入地方都注入完而
Guice 呢则是在使用时候去注射运行效率和灵活性高
类耦合度 耦合度低强调类非侵入以外部化方式处理依赖关系类里边是很干净在配置文件里做文章对类依赖性
极低 高代码级标注DI标记@inject侵入代码中耦合到了类层面上来何止侵入简直侵略代码耦合了过多guice
西大大背离了依赖注入初衷对于代码可维护性可读性均不利
类编写时 需要编写xml配置Bean配置注入 只需声明为@inject,等着被注入

最后在统Module里声明注入方式
仅支持IOC 否spring 目前已经涉猎很多部分 是目前仅仅是个DI容器
是否易于代码重构 统xml配置入口更改容易 配置工作是在Module里进行和spring 异曲同功
支持多种注入方式 构造器ter思路方法 Field,构造器ter思路方法
灵活性 1,如果同个接口定义引用需要注入区别实现就要编写区别Module烦琐

2,动态注入

如果你想注射个实现你还未知呢如何办呢spring 是没办法事先在配置文件里写死而Guice 就可以做到就是说
我想注射这个对象我还不知道注射给谁呢是在运行时才能得到这个接口实现所以这就大大提高了依赖注射灵活
性动态注射
和现有框架集成度 1高众多现有优秀框架(如struts1.x等)均提供了spring 集成入口而且spring 已经不仅仅是依
赖注入包括众多方面

2Spring 也提供了对Hibernate等集成可大大简化开发难度

3提供对于orm,rmi,webservice等等接口众多体系庞大 1可以和现有框架集成不过仅仅依靠个效率稍高
DI就想取代spring 地位有点难度
配置复杂度 在xml中定位类和类的间关系,难度低 代码级定位类和类的间关系,难度稍高

再借斧子例子说说springguice 区别

看下边对于区别社会形态下个人(java对象者)需要把斧子(java对象被者)例子:

(1)原始社会时劳动社会基本没有分工需要斧子人(者)只好自己去磨把斧子每个人拥有自己斧子如果把大家
石斧改为铁斧需要每个人都要学会磨铁斧本领工作效率极低

对应Java里情形是:java里者个被者例子类耦合度极高修改维护烦琐效率极低

(2)工业社会时工厂出现斧子不再由普通人完成而由工厂生产当人们需要斧子时候可以到工厂购买斧子无需
关心斧子是如何制造出来如果废弃铁斧为钢斧只需改变工厂制造工艺即可制作工艺是工厂决定工厂生产什么斧
子工人们就得用什么斧子

对应Java里情形是:Java者可以以来简单工厂创建被者变化点被隔离到了简单工厂里虽然耦合度降低但是者
会和工厂耦合而且需要定位自己工厂

(3)近代工业社会工厂蓬勃发展人们需要什么斧子只需要提供个斧子图形商家会按照你提供图形将你斧子订
做好送上门

对应Java里情形:spring 依赖注入

(4)进入按需要分配社会信息进入现代化人们不再去工厂购买斧子不再拘泥于需要什么斧子事先画好什么样
图形只需要打个电话描述下需要什么类型斧子或许想打造个物美价廉斧子商家会根据市场零件价格计算出最优
制作工艺打造最适合斧子送过来更加信息化更加人性化

对应Java里情形:基于描述注入动态灵活简单注入如:Guice

对于该不该使用Guice 我想也是仁者见仁智者见智就象好多论坛里动不动有人会在那里讨论到底学Java还
是学.net或者是使用eclipse还是Jbuilder这类无聊话题适合和满足项目需求又能省工省力简单完成工作就是最

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值