- 浏览: 312325 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (185)
- C# (8)
- Java (21)
- Oracle (25)
- mysql (3)
- SQLite (9)
- PHP (0)
- 虚拟机 (6)
- Tomcat (5)
- WebService (9)
- Linux (4)
- Windows (0)
- 域名和空间 (5)
- 测试 (1)
- Javascript (2)
- cache (1)
- 认证 (1)
- 图形报表 (1)
- Eclipse&plugins (1)
- struts2 (2)
- Swing (2)
- maven (1)
- BAT (3)
- JqueryUI (1)
- WEB (1)
- Jquery (1)
- 软件 (1)
- Google (1)
- sitemesh (1)
- Spring (1)
- 字体 (1)
- log4j (1)
- 日志级别 (1)
- 控制中心 (1)
- Log4jManager (1)
- log4j.jsp (1)
最新评论
-
chao_t:
不可以喃,楼主
实时控制log4j日志输出级别-Log4J日志级别控制中心 -
zercle:
感谢分享,还在下载中,一直都用plsql,昨天听别人说toad ...
Toad for Oracle 11绿色版本,加上plsql developerv9.0.1.1613 -
cmland:
赞一个,可以使用
Toad for Oracle 11绿色版本,加上plsql developerv9.0.1.1613 -
mozheshashou:
大哥 关键是那个服务器端怎么写啊 ,求指教啊,
说说JSON和JSONP,也许你会豁然开朗,含jQuery用例 -
bjxyj:
net.sourceforge.jdbclogger.Jdbc ...
p6spy的替代品:jdbc logger
RMI、Hessian、Burlap、Httpinvoker、WebService的比較
一、综述
本文比较了RMI、Hessian、Burlap、Httpinvoker、WebService5这种通讯协议的在不同的数据结构和不同数据量时的传输性能。
RMI是java语言本身提供的远程通讯协议,稳定高效,是EJB的基础。但它只能用于JAVA程序之间的通讯。
Hessian和Burlap是caucho公司提供的开源协议,基于HTTP传输,服务端不用开防火墙端口。协议的规范公开,可以用于任意语言。
Httpinvoker是SpringFramework提供的远程通讯协议,只能用于JAVA程序间的通讯,且服务端和客户端必须使用SpringFramework。
Web service是连接异构系统或异构语言的首选协议,它使用SOAP形式通讯,可以用于任何语言,目前的许多开发工具对其的支持也很好。
测试结果显示,几种协议的通讯效率依次为:
RMI > Httpinvoker >= Hessian >> Burlap >> web service
RMI不愧是JAVA的首选远程调用协议,非常高效稳定,特别是在大数据量的情况下,与其他通讯协议的差距尤为明显。
HttpInvoker使用java的序列化技术传输对象,与RMI在本质上是一致的。从效率上看,两者也相差无几,HttpInvoker与RMI的传输时间基本持平。
Hessian在传输少量对象时,比RMI还要快速高效,但传输数据结构复杂的对象或大量数据对象时,较RMI要慢20%左右。
Burlap仅在传输1条数据时速度尚可,通常情况下,它的毫时是RMI的3倍。
Web Service的效率低下是众所周知的,平均来看,Web Service的通讯毫时是RMI的10倍。
二、结果分析
1、直接调用
直接调用的所有毫时都接近0,这说明程序处理几乎没有花费时间,记录的全部时间都是远程调用耗费的。
2、RMI调用
与设想的一样,RMI理所当然是最快的,在几乎所有的情况下,它的毫时都是最少的。特别是在数据结构复杂,数据量大的情况下,与其他协议的差距尤为明显。
为
了充分发挥RMI的性能,另外做了测试类,不使用Spring,用原始的RMI形式(继承UnicastRemoteObject对象)提供服务并远程调
用,与Spring对POJO包装成的RMI进行效率比较。结果显示:两者基本持平,Spring提供的服务还稍快些。
初步认为,这是因为Spring的代理和缓存机制比较强大,节省了对象重新获取的时间。
3、Hessian调用
caucho
公司的resin服务器号称是最快的服务器,在java领域有一定的知名度。Hessian做为resin的组成部分,其设计也非常精简高效,实际运行情
况也证明了这一点。平均来看,Hessian较RMI要慢20%左右,但这只是在数据量特别大,数据结构很复杂的情况下才能体现出来,中等或少量数据
时,Hessian并不比RMI慢。
Hessian的好处是精简高效,可以跨语言使用,而且协议规范公开,我们可以针对任意语言开发对其协议的实现。目前已有实现的语言有:java, c++, .net, python, ruby。还没有delphi的实现。
另
外,Hessian与WEB服务器结合非常好,借助WEB服务器的成熟功能,在处理大量用户并发访问时会有很大优势,在资源分配,线程排队,异常处理等方
面都可以由成熟的WEB服务器保证。而RMI本身并不提供多线程的服务器。而且,RMI需要开防火墙端口,Hessian不用。
4、Burlap调用
Burlap与Hessian都是caucho公司的开源产品,只不过Hessian采用二进制的方式,而Burlap采用xml的格式。
测试结果显示,Burlap在数据结构不复杂,数据量中等的情况下,效率还是可以接受的,但如果数据量大,效率会急剧下降。平均计算,Burlap的调用毫时是RMI的3倍。
我认为,其效率低有两方面的原因,一个是XML数据描述内容太多,同样的数据结构,其传输量要大很多;另一方面,众所周知,对xml的解析是比较费资源的,特别对于大数据量情况下更是如此。
5、HttpInvoker调用
HttpInvoker是SpringFramework提供的JAVA远程调用方法,使用java的序列化机制处理对象的传输。从测试结果看,其效率还是可以的,与RMI基本持平。
不过,它只能用于JAVA语言之间的通讯,而且,要求客户端和服务端都使用SPRING框架。
另外,HttpInvoker 并没有经过实践的检验,目前还没有找到应用该协议的项目。
6、web service调用
本次测试选用了apache的AXIS组件作为WEB SERVICE的实现,AXIS在WEB SERVICE领域相对成熟老牌。
为了仅测试数据传输和编码、解码的时间,客户端和服务端都使用了缓存,对象只需实例化一次。但是,测试结果显示,web service的效率还是要比其他通讯协议慢10倍。
如果考虑到多个引用指向同一对象的传输情况,web service要落后更多。因为RMI,Hessian等协议都可以传递引用,而web service有多少个引用,就要复制多少份对象实体。
Web service传输的冗余信息过多是其速度慢的原因之一,监控发现,同样的访问请求,描述相同的数据,web
service返回的数据量是hessian协议的6.5倍。另外,WEB SERVICE的处理也很毫时,目前的xml解析器效率普遍不高,处理xml
<->
bean很毫资源。从测试结果看,异地调用比本地调用要快,也从侧面说明了其毫时主要用在编码和解码xml文件上。这比冗余信息更为严重,冗余信息占用的
只是网络带宽,而每次调用的资源耗费直接影响到服务器的负载能力。(MS的工程师曾说过,用WEB SERVICE不能负载100个以上的并发用户。)
测试过程中还发现,web service编码不甚方便,对非基本类型需要逐个注册序列化和反序列化类,很麻烦,生成stub更累,不如spring + RMI/hessian处理那么流畅简洁。而且,web service不支持集合类型,只能用数组,不方便。
【2】Java远程调用方法性能比较
【IT168技术】现在,Java远程调用方法很多,各种方法的优缺点网络上也有很多的参考文章,这次我对几个典型的Java远程调用方法做了一个简单的性能分析比较,可供大家参考。
测试环境
CPU:奔腾双核 T4500,内存:DDR3-1067 2G,Web容器:Tomcat6.0.33,操作系统:WinXP-sp3
测试项目
①RMI:用Spring3集成发布。
②hessian:用Spring3集成发布到Tomcat容器。
③Java6 WebService:使用Java6原生WebService和注解,直接用Endpoint.publish发布服务。
④CXF:用Spring3集成发布到Tomcat容器。
测试结果
说明:以上测试虽不是非常的精确,但基本能说明一定的问题。每项案例的服务端方法,都是简单方法,接收客户端传递的一个String类型参数,并打印
到console。每轮测试取三次时间的平均值。所有单线程访问测试全部完成并正常处理请求,没有请求拒绝情况发生。而并发访问测试,除hessian中
途抛异常无法完成,其余均正常完成测试。
结论:
RMI的性能最高,这已是公认,RMI底层基于Java远程方法协议(JRMP)和对象序列化技术,而JRMP是直接基于TCP/IP协议的封装,在
网络上传输2 byte的有效数据,对于TCP而言,总共有478 byte被额外传输,而对于RMI,
1645byte被额外传输。可见RMI的效率还是相当不错的。JavaEE标准的EJB就是基于RMI的调用。
hessian是一个轻量级的remoting on
http框架。Hessian没有采用WebService标准的SOAP协议,而是自己实现了一种二进制RPC(Remote Procedure
Call Protocol,远程过程调用协议)协议。Hessian的设计理念就是简单高效,使用 Hessian
传输数据量比Soap协议要小很多。这也是为什么Hessian的性能要高于WebService。但是,尽管它再简单高效,它始终是基于Http协议上
封装的,所以还是比Java的RMI效率要差一些。我看过其他的一些研究测试报告称Hessian在传输少量对象时,比RMI还要快速高效,但传输数据结
构复杂的对象或大量数据对象时,较RMI要慢20%左右。这个结论在我的测试中还真没有发现,也许与测试环境或方法有关系吧。
Java6WebService 和
CXF的性能应该说是基本同级别,前者略高于后者。众所周知WebService是基于Soap协议实现的,而Soap协议是在Http协议基础上的
XML定义和封装。所有的请求和响应都要被转化成符合SOAP标准的XML格式。显然这直接会导致效率的降低。
XML格式的协议是一种易读易理解的协议,但并不高效。解析和组装XML协议数据流都需要耗费系统的处理时间,所以,WebService的性能不如
Hessian。这里要说一下的是Java6原生的WebService,开发起来非常方便,而且无需额外引入一大堆的Jar包。性能又强于CXF,至于
Axis2和Axis1就更不用说,已经有很多测试表明CXF的性能是Axis2的2倍以上,是Axis1的2-6倍。
那么既然RMI性能那么好,为什么我们需要那么多其他的远程调用方式呢?这个问题又引发到了一个原始的真理。越原始越底层的技术效率就越高,但局限性
也就越大。RMI是Java的特性,那么它必须基于JVM运行,也就是说RMI无法跨语言运行。而WebService就不同了,Soap是基于标准
Http协议的,是一种与语言无关的字符级协议,所以它可以更好的实现异构系统的通信。这在我们现实环境中是非常有用的,相信大家还是
WebService用的比较多点吧。
不足:这次的测试,还是存在很多不足之处。
【3】远程调用服务池或者服务工厂
在现代 J2EE 企业应用系统中,存在着 Hessian 、 HttpInvoker 、 XFire 、 Axis
等多种形式的远程调用技术。尽管有 Spring
等框架对这些技术进行了封装,降低了使用的复杂度,但对普通程序员而言仍是复杂的——至少需要要掌握这些技术的基础知识。
无论使用那种技术,其基本原理都是一样的:服务端生成骨架,对外暴露服务;客户端生成服务代理,访问调用服务。通常情况下,生成服务代理的代价比较高昂,
这也是我们第一次访问远程服务速度比较慢的原因,为每个请求生成新的服务代理恐怕不是我们所期望的。更何况,如果采用这种方式,就要在代码里针对各种不同
的技术(如 XFire 、 HttpInvoker
)编写不同的服务生成和调用的处理代码。不仅麻烦,而且容易出错。我想,没有人愿意去直接操作各种框架技术的底层代码,这并不是一个好注意!
作为一种替代方案,我们设计了一个“服务池”的功能,或者说“服务工厂”更贴切一点。先看下面这张类图:
如上图所示,针对 HttpInvoker 、 XFire 、 Hessian
等各种远程调用技术,抽象出一个“远程服务池”(服务工厂)既 RemoteServicePool
接口。该接口提供了获取服务及一些其他的辅助功能,并针对 HttpInvoker 、 XFire 、 Hessian
等不同技术提供了相应的具体实现。采用这种方式,开发人员只需在代码中“注入” RemoteServicePool ,并以统一的方式(如
getService()
)获取实际的服务,只是针对不同技术在配置上有些须差异而已。该技术的原理非常简单,在应用启动之前把所有存在的服务提供者提供的服务都配置好,并为它们
分配一个唯一的 ID 。应用启动之后,框架会自动生成和这些地址相对应的服务代理( ServiceProxy
),这些代理已经是可用的服务,服务获取的细节被完全屏蔽掉,开发者只要知道如何从 RemoteServicePool
中获取服务就可以了。看一下服务池的接口定义:
java 代码
1. /**
2. * 远程服务缓冲池。
3. *
4. *
5. * 对于一个既定的服务契约(既接口),可以有很多服务提供者( ServiceProvider )。该接口的提出,是为了解决服务访问者和服务提供者之间 “ 一对多 ” 的关系。
6. *
7. * @author Tony
8. */
9.
10. public interface RemoteServicePool {
11.
12. /**
13. * 从缓冲池中获取一个 Service 。
14. *
15. *
16. * 此处获得的是一个
Object
,需要调用者自己做类型转换。
17. *
18. *
19. * 参数 serviceId 代表服务缓冲池中的一个实例名称。服务类型采用配置文件中默认的类型。
20. *
21. * @param serviceId
22. * 实例名称
23. *
24. * @return 服务对象
25. */
26.
27. Object getService(String serviceId);
28.
29. }
xml 代码
1. <bean id="userServicePool" class="com. tonysoft .common.XFireRemoteServicePool">
2. <property name="serviceInterface">
3. <value>com. tonysoft .demo.service.UserServicevalue>
4. property>
5. <property name="serviceUrls">
6. <map>
7. <entry key=" server 1 ">
8. <value>http://localhost:8080/server1/service/userService?WSDLvalue>
9. entry>
10. <entry key="server2">
11. <value>http://localhost:8080/server2/service/userService?WSDLvalue>
12. entry>
13. map> J2EE 企业应用系统中,存在着 Hessian 、 HttpInvoker 、
XFire 、 Axis 等多种形式的远程调用技术。尽管有 Spring
等框架对这些技术进行了封装,降低了使用的复杂度,但对普通程序员而言仍是复杂的——至少需要要掌握这些技术的基础知识。
14. property> 接下来看看如何配置服务:
15. bean>
最后再来看一下访问服务的代码:
java 代码
1. /** 服务工厂 */
2. public RemoteServicePool userServicePool ;
3. /**
4. * 测试新增一个不存在的用户。
5. */
6.
7. public void testAddUser() {
8.
9. UserService userService = null ;
10. try {
11. userService =(UserService) userServicePool .getService("server2");
12. } catch (Exception e){
13. throw new RuntimeException( " 获取服务失败,失败原因:" + e);
14. }
15.
16. OperateResult result = userService .addUser( new User( "daodao" , " 技术部" ));
17.
18. assertEquals(result.isSuccess(), true );
19.
20. }
该方案还为“双向关联”的系统服务提供了一个很好解决办法。看下面一张图:
如图,系统 B 和系统 C 都调用系统 A 进行付款操作;同时系统 A 要用远程服务向系统 B 或系统 C
进行认证操作,认证操作的接口(契约)都是一样的,业务逻辑可能有所差异。在这种情况下,配置在系统 A
中的认证服务就比较麻烦,因为要根据不同的系统调用认证服务,既从 B 过来的请求要访问 B 的认证服务,从 C 过来的请求要访问 C
的认证服务。用服务池可以很好的解决这个问题,把两个系统( B 、 C )提供的认证服务地址都配置在同一个服务池中,根据不同的 ID (如 B 、
C )来决定使用那个系统的服务。
ServiceResportApplication.rar
描述:
下载
文件名: ServiceResportApplication.rar
文件大小: 49 KB
下载过的: 文件被下载或查看 104 次
尽管服务池解决了一些问题,在某种程度上降低了复杂度,但仍存在如下一些问题:
服务的运行期动态注册
服务的自动注入( IoC )
透明化服务 ID 的传递
在服务池( ServicePool )概念的基础上进行扩展,我们得出了如下的系统模型:
在核心位置上是一个服务中心资源库( ServiceRepository
),存储了系统中用到的所有的远程服务。服务采取动态注册的机制,由对外提供的服务注册器( ServiceRegister
)提供服务注册功能。外部系统可以实现该接口向资源中心注册服务。提供了一个启动时运行的注册器,可以把静态配置在系统中的服务都注册进来。
服务的生成、管理等均由服务中心自己维护,委托服务代理生成器( ServiceProxyGenerator
)完成服务的创建。可以针对现有的远程调用方式,如 XFire,HttpInvoker,Hessian
等创建服务代理,也可以针对自己定义的远程调用方式创建服务代理,由 CustomServiceProxyGenerator 完成该功能。
一个服务模型包括 5 个因素:
服务接口 serviceClass
服务 ID serviceId
服务类型 serviceType
服务地址 serviceUrl
附加属性 props
查找一个服务需要两个因素,一个是服务接口,另一个是服务 ID 。这两个因素共同决定了一个服务,既服务中心内部的“服务 ID ”。通过这种方式,可以允许存在多个 ID 相同但接口不同的服务,也可以存在多个接口相同但 ID 不同的服务。
服务 ID 的获取是系统中一个关键的功能,这部分对程序员来说应该是透明的,由系统自己维护。相应的提供了一个服务 ID 提供者 (ServiceIdProvider) 接口,由实现该接口的子类完成服务 ID 获取功能(这是比较关键的地方,需要特殊考虑)。
对于程序员来说,使用服务中心里的服务再也不能比这样再简单了!看看配置:
xml 代码
1. < bean id = "helloHttpInvokerService" parent = "abstractServiceProxyFactory" >
2. < property name = "serviceInterface" >
3. < value > com.tonysoft.common.service.repository.example.HelloHttpInvoker value >
4. property >
5. bean >
再看如何使用这个 bean :
1. private HelloHttpInvoker helloHttpInvokerService ;
2. public void testHttpInvoker() {
3. assertNotNull( "helloHttpInvokerService can't be null !" , helloHttpInvokerService );
4. assertEquals ( "Hello , HttpInvoker !" , helloHttpInvokerService .sayHello());
5. }
6. /**
7. * @param helloHttpInvokerService
8. * the helloHttpInvokerService to set
9. */
10.
11. public void setHelloHttpInvokerService(HelloHttpInvoker helloHttpInvokerService) {
12. this . helloHttpInvokerService = helloHttpInvokerService;
13. }
就是这样的简单! Spring 会把这个 bean 自动注入到程序中,可以象使用其他任何 bean
一样使用它!程序员完全不用关心该服务由谁提供、采用什么技术,他只要知道系统中存在这样一个服务就 OK
了。该技术彻底向程序员屏蔽了底层技术的实现细节,以统一的方式访问任何形式的远程服务。至于服务是如何生成、如何配置的将在后面叙述。
服务( Service Bean )是如何实现自动注入( IoC )的呢?
注意到上面配置的 bean 都继承了“ abstractServiceProxyFactory ”,它是一个工厂 bean ,负责根据给定的接口类型,到服务中心( ServiceRepository )查找服务,并生成服务代理。我们来看一下它的核心代码:
java 代码
1. /**
2. * 服务代理工厂。
3. *
4. *
5. * 该工厂对程序员屏蔽了服务实现的技术细节,对于 XFire 、 Hessian 、 HttpInvoker 等常用远程服务形式进行封装。
6. *
7. *
8. * 程序员只需要提供一个服务接口(契约),该工厂会从服务中心
ServiceRepository
中查找符合该接口的远程服务实例。
9. *
10. *
11. * 查找的规则是由服务 ID 提供者所提供的服务 ID 和服务接口名字共同组成的服务关键字匹配。
12. *
13. * @author Tony
14. */
15. public class ServiceProxyFactory implements FactoryBean {
16.
17. /** 服务中心 */
18. private ServiceRepository serviceRepository ;
19.
20. /** 服务 ID 提供者 */
21. private ServiceIdProvider serviceIdProvider ;
22. /** 服务接口 */
23. private Class serviceInterface ;
24. /**
25. * @see org.springframework.beans.factory.FactoryBean#getObject()
26. */
27. public Object getObject() throws Exception {
28. return ProxyFactory.getProxy(getObjectType(), new ServiceProxyInterceptor());
29. // return serviceRepository.getService(serviceInterface, serviceIdProvider.getCurrentServiceId());
30. }
31. /**
32. * @see org.springframework.beans.factory.FactoryBean#getObjectType()
33. */
34. public Class getObjectType() {
35. return serviceInterface ;
36. }
37. /*
38. * @see org.springframework.beans.factory.FactoryBean#isSingleton()
39. */
40. public boolean isSingleton() {
41. return true ;
42. }
43. /*
44. * 远程服务代理拦截器。
45. */
46. private class ServiceProxyInterceptor implements MethodInterceptor {
47. /*
48. * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
49. */
50. public Object invoke(MethodInvocation invocation) throws Throwable {
51. Method method = invocation.getMethod();
52. Object[] args = invocation.getArguments();
53. Object client = getClient();
54. return method.invoke(client, args);
55. }
56. private Object getClient() {
57. try {
58. return serviceRepository .getService( serviceInterface , serviceIdProvider .getCurrentServiceId());
59. } catch (ServiceException e) {
60. // TODO
61. e.printStackTrace();
62. return null ;
63. }
64. }
65. }
66. // ---- 容器自动注入 ----
67. ••••••
真正的魅力就在这个地方。根据服务接口类型和服务 ID ,从服务中心获取特定的服务。服务接口是配置好的, 而服务 ID
则在运行时才能确定,根据不同的应用、不同的策略提供不同的 ServiceIdProvider 。其中用到了 Spring 的
FactoryBean 和拦截器,至于为什么要在这里使用拦截器,可以参考 Spring 框架的源码。
服务代理生成器( ServiceProxyGenerator )也是一个值得一提的地方,我们先看一下它的接口:
1. /**
2. * 服务代理生成器。
3. *
4. * @author Tony
5. */
6. public interface ServiceProxyGenerator {
7.
8. /**
9. * 取得服务代理对象。
10. *
11. * @param serviceClass
12. * 服务接口
13. * @param serviceUrl
14. * 服务地址
15. * @param props
16. * 附加属性
17. * @return 代理对象
18. * @throws Exception
19. */
20. Object getService(Class serviceClass, String serviceUrl, Properties props) throws Exception;
21. }
22.
23. /*它只有一个 getService() 方法,那么为什么设计这个接口?在什么地方使用呢?回答这个问题之前先来看看下面这段代码: */
24. public void registService(ServiceModel serviceModel) throws ServiceException {
25. ••••••
26. String key = serviceModel.getServiceId() + KEY_SPAR
27. + serviceModel.getServiceClass().getName();
28. if ( serviceNames .contains(key)) {
29. throw new ServiceRegistException( "service is exist!" );
30. }
31. Object proxy = null ;
32. try {
33. ServiceProxyGenerator proxyGenerator = (ServiceProxyGenerator) beanFactory
34. .getBean(serviceModel.getServiceType() + PROXY_GENERATOR_END );
35. proxy = proxyGenerator.getService(serviceModel.getServiceClass(), serviceModel
36. .getServiceUrl(), serviceModel.getProps());
37. } catch (Exception e) {
38. throw new ServiceRegistException( "can't regist service !" , e);
39. }
40. if (proxy != null ) {
41. serviceNames .add(key);
42. serviceContainer .put(key, proxy);
43. } else {
44. throw new ServiceRegistException( "fail to regist service !" );
45. }
46. }
上面做特殊标记的代码就是应用服务代理生成器的地方,这里我们用到了 Spring 的 bean 工厂,根据注册服务的类型(
xfire,httpinvoker,hessian 等)到 Spring
容器里查找相应的生成器,并生成指定类型的服务。看下面配置的几个服务代理生成器:
xml 代码
1. <!-- XFire 类型服务代理生成器 -->
2. < bean id = "xfire_generator" class =
"com.tonysoft.common.service.repository.generator.XFireServiceProxyGenerator"
lazy-init = "true" >
3. < property name = "serviceFactory" >
4. < ref bean = "xfire.serviceFactory" />
5. property >
6. bean >
7.
8. <!-- Hessian 类型服务代理生成器 -->
9. < bean id = "hessian_generator" class =
"com.tonysoft.common.service.repository.generator.HessianServiceProxyGenerator"
lazy-init = "true" >
10. bean >
11.
12. <!-- HttpInvoker 类型服务代理生成器 -->
13. < bean id = "httpinvoker_generator" class =
"com.tonysoft.common.service.repository.generator.HttpInvokeServiceProxyGenerator"
lazy-init = "true" >
14. bean >
15.
16. <!-- 自定义 类型服务代理生成器 -->
17. < bean id = "custom_generator" class =
"com.tonysoft.common.service.repository.generator.CustomServiceProxyGenerator"
lazy-init = "true" >
18. bean >
19.
20. <!-- 服务中心(资源库) -->
21. < bean id = "serviceRepository" class = "com.tonysoft.common.service.repository.DefaultServiceRepository" >
22. bean >
23.
24. <!-- 服务 ID 提供者 -->
25. < bean id = "serviceIdProvider" class =
"com.tonysoft.common.service.repository.provider.DefaultServiceIdProvider"
>
26. bean >
27. <!-- 所有远程服务的基础类 -->
28. < bean id = "abstractServiceProxyFactory" class =
"com.tonysoft.common.service.repository.ServiceProxyFactory" abstract =
"true" >
29. bean >
简单看一下 HttpInvoker 类型服务代理生成器的代码:
java 代码
1. public class HttpInvokeServiceProxyGenerator implements ServiceProxyGenerator {
2.
3. /** HttpInvoker 服务代理工厂 */
4. private HttpInvokerProxyFactoryBean httpInvokerFactory = new HttpInvokerProxyFactoryBean();
5. /*
6. * @see com.alipay.xfiredemo.common.ServiceProxyGenerator#getService(java.lang.Class, java.lang.String,
7. * java.util.Properties)
8. */
9. public Object getService(Class serviceClass, String serviceUrl, Properties props) {
10. // Todo initial httpInvokerFactory with props
11. httpInvokerFactory .setServiceInterface(serviceClass);
12.
13. httpInvokerFactory .setServiceUrl(serviceUrl);
14.
15. // must invoke this method
16. httpInvokerFactory .afterPropertiesSet();
17.
18. return httpInvokerFactory .getObject();
19.
20. }
21.
22. }
是的,正如你所看到的一样,我们这里把真正生成服务代理的任务交给了 Spring 的 HttpInvokerProxyFactoryBean 来完成。
提供在初始化时注册的静态服务功能,配制如下:
1. <!-- 初始化时注册的静态服务 -->
2. < bean id = "bootupServiceRegister" class =
"com.tonysoft.common.service.repository.register.BootupServiceRegister"
lazy-init = "false" >
3. < property name = "services" >
4. < list >
5. < bean class = "com.tonysoft.common.service.repository.ServiceModel" >
6. < property name = "serviceClass" ><
value >
com.tonysoft.common.service.repository.example.HelloHttpInvoker value
> property >
7. < property name = "serviceId" >< value > default value > property >
8. < property name = "serviceType" >< value > httpinvoker value > property >
9. < property name = "serviceUrl" >< value > http://localhost:8080/serviceRepositoryApplication...voker/helloHttpInvoker.service
value > property >
10. < property name = "props" >
11. < props > props >
12. property >
13. bean >
14. < bean class = "com.tonysoft.common.service.repository.ServiceModel" >
15. < property name = "serviceClass" ><
value > com.tonysoft.common.service.repository.example.HelloXFire
value > property >
16. < property name = "serviceId" >< value > default value > property >
17. < property name = "serviceType" >< value > xfire value > property >
18. < property name = "serviceUrl" >< value > http://localhost:8080/serviceRepositoryApplication.../xfire/helloXFire.service?WSDL
value > property >
19. < property name = "props" >
20. < props > props >
21. property >
22. bean >
23. list >
24. property >
25. bean >
具体内容可以参看附件中的资源:
一、 ServiceRepository 的源代码( Eclipse 工程)
二、 一个示例应用
三、 打包部署的 ANT 脚本
把项目导入 Eclipse 中,直接运行 Ant 脚本,在 target 目录下会生成服务中心的 jar 包,同时生成示例应用的
war 包,把 war 包放到任意服务器( Server )上并启动服务器并确保应用正常启动。 运行 ServiceRepositoryTest
.java 执行完整的单元测试,观测结果。其他的自己看源码吧。
发表评论
-
Java 实现快递查询 (免费) ,不用输入验证码
2013-05-25 21:54 1659查快递的时候发现了一个http://www.kaidi10 ... -
实时控制log4j日志输出级别-Log4J日志级别控制中心
2013-01-27 01:45 2405动态控制Log4J日志级别,只需要一个JSP页面 ... -
动态加载配置文件类,通用类
2012-07-21 12:13 2217package config; import java. ... -
Java 修复HTML标签
2012-07-03 14:15 1772开源的组件:http://sourceforge.net/pr ... -
正则表达式中的java 转义字符
2012-05-08 22:19 1678java 的转义字符,在正则表达式中应用 ... -
java解析SQL脚本
2012-05-08 22:17 1562/** * 执行初始化SQL脚本 * @param ... -
Protocol Buffer入门——轻松搭建java环境
2012-04-19 21:49 1236Protocol Buffer入门—— ... -
Jersey framework开发RESTFUL应用
2012-04-19 21:46 1419本文演示环境为eclipse + Maven插件 + J ... -
一个开源的Java快速开发平台
2012-04-10 09:24 1985http://www.j-hi.net/ J-HI是一 ... -
apache common DurationFormatUtils
2012-04-01 10:42 1190日期相減(兩日期相差多少天,月,年): Date d1 ... -
使用Perf4J进行性能分析和监控
2012-04-01 10:20 1007使用Perf4J进行性能分析和监控 作者 ... -
jsoup 是一款 Java 的HTML 解析器
2012-03-21 23:31 1116jsoup 是一款 Java 的HTML 解析器,可 ... -
struts2-redirect和redirect-action的一点区别
2012-03-15 14:23 748struts2-redirect和redirect-actio ... -
t150ckh request.getHeader("user-agent")解析浏览器
2012-03-07 20:18 19972public class BrowseTool { ... -
收邮件、更改邮件标志 javamai +imap
2011-05-09 12:17 1576来源:http://blog.csdn.net/su ... -
UrlRewriteFilter 学习笔记
2011-01-18 16:18 17301、简介 UrlRewriteFilter是 ... -
java.lang.SecurityException: Prohibited package name
2011-01-02 15:39 3075问题 java.lang.SecurityExceptio ... -
Java 线程Join的用法
2010-11-18 10:11 1022在上面的例子中多次使用到了Thread类的join方法。我想大 ... -
Java 守护线程与非守护线程的区别
2010-11-18 10:05 2490ublic static void main ... -
关于JAVA中enum枚举类型的思考
2010-10-31 09:58 1369package utils; /** * @ ...
相关推荐
公司内部讲义,比较了SOA,RMI和Spring HttpInvoker。并介绍了Spring HttpInvoker的基本使用方法。
这种方式相比于传统的RMI或者Hessian,更加灵活且易于理解,因为它完全基于HTTP标准,可以利用现有的HTTP基础设施。 二、SpringBoot集成HTTP Invoker 1. 添加依赖:在Spring Boot项目中,我们需要添加`spring-boot...
但当传递过来的RPC消息中包含序列化对象时,RMI完胜Hessian和Burlap了。 因为Hessian和Burlap都是采用了私有的序列化机制,而RMI使用的是Java本身的序列化机制。如果数据模型非常复杂,那么Hessian/Burlap的序列...
本文将深入探讨标题和描述中提及的几个关键知识点:Jmail、HttpInvoker、AOP(面向切面编程)、RMI(远程方法调用)以及定时任务。这些技术在实际开发中都有着广泛的应用。 首先,Jmail是一个用于发送电子邮件的...
本压缩包“DuBBo(rmi+Hessian).zip”提供了关于Dubbo如何与RMI(Remote Method Invocation)和Hessian两种通信协议结合使用的深入学习资料。下面我们将详细探讨这两个知识点。 首先,RPC(Remote Procedure Call)...
【标题】:“CXF+RMI+HESSIAN”整合详解 在IT行业中,CXF、RMI(Remote Method Invocation)和HESSIAN是三种不同的技术,它们在分布式系统和服务提供方面发挥着重要作用。这篇文章将深入探讨这三者如何协同工作以...
相比于RMI(远程方法调用)和其他远程调用技术,HttpInvoker具有更好的网络穿透性和兼容性,更适合于分布式系统间的跨域通信。 **2. HttpInvoker的工作原理** - **服务端配置**:在服务端,我们需要定义一个接口,...
<bean id="myServiceExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> ``` 服务端还需要一个Servlet容器,如Tomcat,部署Spring应用上下文,并配置一个...
如果你的参数和返回值是比较复杂的,通过httpInvoker有巨大的优势。 1. 远程访问流程 1) 服务端定义服务接口 2) 服务端实现服务接口 3) 暴露服务对象 4) 客户端定义暴露的服务端接口 5) 客户端配置服务参数 6) ...
<bean id="httpInvokerExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> ``` 这将把`MyRemoteService`接口暴露为HTTP服务,客户端可以通过HTTP请求调用`doSomething`...
<bean id="serviceExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> ``` 这里,`ServiceImpl`是你实现`ServiceInterface`的具体类,`HttpInvokerServiceExporter`将...
这是一个zip包,里面包含有“5对”独立的WebService项目,包含了各种WebService技术:包括Apache的JAX、Hessian、HttpInvoker、SpringJAX、RMI的客户端和服务器端的部署方式。无需任何数据库配置,每项WS技术包含有...
HttpInvoker是Spring框架中的一种远程调用机制,主要用于在分布式系统中实现服务间的通信。它基于HTTP协议,允许客户端通过HTTP请求调用服务端的方法,实现了远程方法的透明调用。这个"HttpInvoker Sample"是一个...
6. **性能优化**:虽然HTTP Invoker相比RMI有更高的网络开销,但可以通过一些手段优化,例如使用HTTP连接池,减少HTTP请求的建立和关闭次数,或者使用GZIP压缩来减小数据传输量。 7. **故障恢复**:HTTP Invoker...
- **性能**:相比RMI或Thrift等二进制协议,HTTP Invoker可能有更高的网络开销。 - **安全性**:HTTP通信可能面临中间人攻击,需要额外的安全措施。 总结,Java Spring 2.5 Remote Invoke HTTP Invoker是一个实用的...
而Spring-RMI(Remote Method Invocation)和HTTP调用是Spring框架中两种不同的远程通信机制,它们使得分布式系统间的交互变得简单易行。 **Spring-RMI** RMI是Java中的一种远程方法调用技术,允许对象在不同JVM...
远程调用方法就是HttpInvoker:他也是将参数和返回值通过Java的序列化机制进行编组和反编组,它具有RMI的支持所有可序列化对象的优点。试使用Http协议传输二进制流的,同时又具有Hessian、Burlap(传输xml文本)的...