- 浏览: 1473658 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (798)
- struts2 (42)
- servlet (20)
- quartz (4)
- jquery & ajax (24)
- tomcat (5)
- javascript (15)
- struts1 (8)
- 搜索关键字及链接 (3)
- fckeditor (3)
- Apache (5)
- spring (22)
- linux (3)
- 企业应用 (8)
- 综合应用 (13)
- 服务器 (2)
- 数据库 (85)
- 性能调优 (21)
- 网络应用 (15)
- 缓存技术 (8)
- 设计模式 (39)
- 面试题 (7)
- 程序人生&前辈程序员 (29)
- java基础 (59)
- hibernate (75)
- log4j (4)
- http (11)
- 架构设计 (28)
- 网页设计 (12)
- java邮件 (4)
- 相关工具 (11)
- ognl (7)
- 工作笔记 (18)
- 知识面扩展 (12)
- oracle异常 (1)
- 正则表达式 (2)
- java异常 (5)
- 项目实践&管理 (1)
- 专业术语 (11)
- 网站参考 (1)
- 论坛话题 (2)
- web应用 (11)
- cxf&webservice (22)
- freemarker (3)
- 开源项目 (9)
- eos (1)
- ibatis (6)
- 自定义标签 (3)
- jsp (3)
- 内部非公开文档(注意:保存为草稿) (0)
- 国内外知名企业 (2)
- 网店 (3)
- 分页 (1)
- 消费者习惯 (2)
- 每日关注 (1)
- 商业信息 (18)
- 关注商业网站 (1)
- 生活常识 (3)
- 新闻 (2)
- xml&JSON (5)
- solaris (1)
- apache.common (3)
- BLOB/CLOB (1)
- lucene (2)
- JMS (14)
- 社会进程 (8)
- SSH扩展 (2)
- 消费心理 (1)
- 珠三角 (1)
- 设计文档 (1)
- XWork&webwork (1)
- 软件工程 (3)
- 数据库及链接 (1)
- RMI (2)
- 国内外知名企业&人物 (1)
最新评论
-
司c马:
简介易懂、
OutputStream和InputStream的区别 -
在世界的中心呼喚愛:
解决我的问题
Java获取客户端的真实IP地址 -
bo_hai:
都是些基本的概念呀!
SSO -
tian_4238:
哥们,你也是搞水利这块的吧。
巧用SQLQuery中的addScalar -
loveEVERYday:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp小结
在应用开发中,常常涉及服务器系统中各种不同进程之间的通信与计算交互,远端调用(RMI)是实现这种计算场景的一种有效方式。此外,还存在着另一种情况,在这种应用场景中,与那些典型的基于HTML的B/S应用不同,客户端程序需要完成对服务器端应用的直接调用,这也是需要远端调用大显身手的场合。
Spring中提供了轻量级的远端调用模块,从而为我们在上面提到的应用场景开发,提供平台支持。根据Spring的既定策略,它依然只是起到一个集成平台的作用,而并不期望在实现方案上,与已有的远端调用方案形成竞争。也就是说,在Spring远端调用架构中,具体的通信协议设计、通信实现,以及在服务器和客户端对远端调用的处理封装,Spring没有将其作为实现重点,在这个技术点上,并不需要重新发明轮子。对Spring来说,它所要完成的工作,是在已有远端调用技术实现的基础上,通过IoC与AOP的封装,让应用更方便地使用这些远端调用服务,并能够更方便灵活地与现有应用系统实现集成。通过Spring封装以后,应用使用远端过程调用非常方便,既不需要改变原来系统的相关实现接口,也不需要为远端调用功能增加新的封装负担。因此,这种使用方式,在某种程度上,可以称为轻量级的远端调用方案。
在实现远端调用的过程中,往往需要涉及客户端和服务器端的相关设置,这些设置通过Spring的IoC容器就可以很好的完成,这是我们已经很熟悉的IoC容器的强项了。同时,Spring为远端调用的实现,提供了许多不同的方案,玲琅满目,任君选择。如RMI、HTTP调用器、第三方远端调用库Hessian/Burlap、基于Java RMI的解决方案,等等。
Spring对不同的远端调用的实现封装,基本上,都采用了类似的模式来完成,比如在客户端,都是通过相关的ProxyFactoryBean和ClientInterceptor来完成的,在服务器端是通过ServiceExporter来导出远端的服务对象的。有了这些统一的命名规则,应用配置和使用远端调用会非常方便,同时,通过对这些Spring远端调用基础设施实现原理的分析,还可以看到一些常用处理方法的技术实现,比如对代理对象的使用、拦截器的使用、通过afterPropertiesSet来启动远端调用基础设施的建立,等等,这些都是在Spring中常用的技术。
HTTP调用器客户端的实现
在HtttpInvokerProxyFactory中,设置了serviceProxy对象作为远端服务的本地代理对象;同时,在依赖注入完成以后,通过afterPropertiesSet来对远端调用完成设置。
Spring中提供了轻量级的远端调用模块,从而为我们在上面提到的应用场景开发,提供平台支持。根据Spring的既定策略,它依然只是起到一个集成平台的作用,而并不期望在实现方案上,与已有的远端调用方案形成竞争。也就是说,在Spring远端调用架构中,具体的通信协议设计、通信实现,以及在服务器和客户端对远端调用的处理封装,Spring没有将其作为实现重点,在这个技术点上,并不需要重新发明轮子。对Spring来说,它所要完成的工作,是在已有远端调用技术实现的基础上,通过IoC与AOP的封装,让应用更方便地使用这些远端调用服务,并能够更方便灵活地与现有应用系统实现集成。通过Spring封装以后,应用使用远端过程调用非常方便,既不需要改变原来系统的相关实现接口,也不需要为远端调用功能增加新的封装负担。因此,这种使用方式,在某种程度上,可以称为轻量级的远端调用方案。
在实现远端调用的过程中,往往需要涉及客户端和服务器端的相关设置,这些设置通过Spring的IoC容器就可以很好的完成,这是我们已经很熟悉的IoC容器的强项了。同时,Spring为远端调用的实现,提供了许多不同的方案,玲琅满目,任君选择。如RMI、HTTP调用器、第三方远端调用库Hessian/Burlap、基于Java RMI的解决方案,等等。
Spring对不同的远端调用的实现封装,基本上,都采用了类似的模式来完成,比如在客户端,都是通过相关的ProxyFactoryBean和ClientInterceptor来完成的,在服务器端是通过ServiceExporter来导出远端的服务对象的。有了这些统一的命名规则,应用配置和使用远端调用会非常方便,同时,通过对这些Spring远端调用基础设施实现原理的分析,还可以看到一些常用处理方法的技术实现,比如对代理对象的使用、拦截器的使用、通过afterPropertiesSet来启动远端调用基础设施的建立,等等,这些都是在Spring中常用的技术。
HTTP调用器客户端的实现
在HtttpInvokerProxyFactory中,设置了serviceProxy对象作为远端服务的本地代理对象;同时,在依赖注入完成以后,通过afterPropertiesSet来对远端调用完成设置。
- public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor
- implements FactoryBean<Object> {
- //这是远端对象的代理
- private Object serviceProxy;
- @Override
- //在注入完成之后,设置远端对象代理
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- //需要配置远端调用的接口
- if (getServiceInterface() == null) {
- throw new IllegalArgumentException("Property 'serviceInterface' is required");
- }//这里使用ProxyFactory来生成远端代理对象,注意这个this,因为HttpInvokerProxyFactoryBean的基类是HttpInvokerClientInterceptor,所以代理类的拦截器被设置为HttpInvokerClientInterceptor
- this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader());
- }
- //FactoryBean生产对象的入口。返回的是serviceProxy对象,这是一个代理对象
- public Object getObject() {
- return this.serviceProxy;
- }
- public Class<?> getObjectType() {
- return getServiceInterface();
- }
- public boolean isSingleton() {
- return true;
- }
public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor
implements FactoryBean<Object> {
//这是远端对象的代理
private Object serviceProxy;
@Override
//在注入完成之后,设置远端对象代理
public void afterPropertiesSet() {
super.afterPropertiesSet();
//需要配置远端调用的接口
if (getServiceInterface() == null) {
throw new IllegalArgumentException("Property 'serviceInterface' is required");
}//这里使用ProxyFactory来生成远端代理对象,注意这个this,因为HttpInvokerProxyFactoryBean的基类是HttpInvokerClientInterceptor,所以代理类的拦截器被设置为HttpInvokerClientInterceptor
this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader());
}
//FactoryBean生产对象的入口。返回的是serviceProxy对象,这是一个代理对象
public Object getObject() {
return this.serviceProxy;
}
public Class<?> getObjectType() {
return getServiceInterface();
}
public boolean isSingleton() {
return true;
}
可以看到,为这个代理对象配置了一个拦截器HttpInvokerClientInterceptor,在这个拦截器中,拦截了对代理对象的方法调用。如以下代码所示:
- //对代理对象的方法调用入口
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
- if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
- return "HTTP invoker proxy for service URL [" + getServiceUrl() + "]";
- }
- //创建RemoteInvocation对象,这个对象封装了对远端的调用,这些远端调用通过序列化的机制完成
- RemoteInvocation invocation = createRemoteInvocation(methodInvocation);
- RemoteInvocationResult result = null;
- try {
- //这里是对远端调用的入口
- result = executeRequest(invocation, methodInvocation);
- }
- catch (Throwable ex) {
- throw convertHttpInvokerAccessException(ex);
- }
- try {//返回远端调用的结果
- return recreateRemoteInvocationResult(result);
- }
- catch (Throwable ex) {
- if (result.hasInvocationTargetException()) {
- throw ex;
- }
- else {
- throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() +
- "] failed in HTTP invoker remote service at [" + getServiceUrl() + "]", ex);
- }
- }
- }
//对代理对象的方法调用入口
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
return "HTTP invoker proxy for service URL [" + getServiceUrl() + "]";
}
//创建RemoteInvocation对象,这个对象封装了对远端的调用,这些远端调用通过序列化的机制完成
RemoteInvocation invocation = createRemoteInvocation(methodInvocation);
RemoteInvocationResult result = null;
try {
//这里是对远端调用的入口
result = executeRequest(invocation, methodInvocation);
}
catch (Throwable ex) {
throw convertHttpInvokerAccessException(ex);
}
try {//返回远端调用的结果
return recreateRemoteInvocationResult(result);
}
catch (Throwable ex) {
if (result.hasInvocationTargetException()) {
throw ex;
}
else {
throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() +
"] failed in HTTP invoker remote service at [" + getServiceUrl() + "]", ex);
}
}
}
远端调用的具体实现过程,是由executeRequest来完成的,也就是在SimpleHttpInvokerRequestExecutor的实现中,封装了整个HTTP调用器客户端实现的基本过程,如下所示:
- //这是HTTP调用器实现的基本过程,通过HTTP的request和reponse来完成通信,在通信的过程中传输的数据是序列化的对象
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
- throws IOException, ClassNotFoundException {
- //打开一个标准J2SE HttpURLConnection
- HttpURLConnection con = openConnection(config);
- prepareConnection(con, baos.size());
- //远端调用封装成RemoteInvocation对象,这个对象通过序列化被写到对应的HttpURLConnection中去
- writeRequestBody(config, con, baos);
- //这里取得远端服务返回的结果,然后把结果转换成RemoteInvocationResult返回
- validateResponse(config, con);
- InputStream responseBody = readResponseBody(config, con);
- return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
- }
- //把序列化对象输出到HttpURLConnection去
- protected void writeRequestBody(
- HttpInvokerClientConfiguration config, HttpURLConnection con, ByteArrayOutputStream baos)
- throws IOException {
- baos.writeTo(con.getOutputStream());
- }
- //为使用HttpURLConnection完成对象序列化,需要进行一系列的配置
- //比如配置请求方式为post,请求属性等等
- protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException {
- con.setDoOutput(true);
- con.setRequestMethod(HTTP_METHOD_POST);
- con.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, getContentType());
- con.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, Integer.toString(contentLength));
- LocaleContext locale = LocaleContextHolder.getLocaleContext();
- if (locale != null) {
- con.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale.getLocale()));
- }
- if (isAcceptGzipEncoding()) {
- con.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
- }
- }
- //获得HTTP响应的IO流
- protected InputStream readResponseBody(HttpInvokerClientConfiguration config, HttpURLConnection con)
- throws IOException {
- //如果是通过gzip压缩,那么需要先解压
- if (isGzipResponse(con)) {
- // GZIP response found - need to unzip.
- return new GZIPInputStream(con.getInputStream());
- }
- else {
- // Plain response found.
- // 正常的HTTP响应输出
- return con.getInputStream();
- }
- }
//这是HTTP调用器实现的基本过程,通过HTTP的request和reponse来完成通信,在通信的过程中传输的数据是序列化的对象
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
throws IOException, ClassNotFoundException {
//打开一个标准J2SE HttpURLConnection
HttpURLConnection con = openConnection(config);
prepareConnection(con, baos.size());
//远端调用封装成RemoteInvocation对象,这个对象通过序列化被写到对应的HttpURLConnection中去
writeRequestBody(config, con, baos);
//这里取得远端服务返回的结果,然后把结果转换成RemoteInvocationResult返回
validateResponse(config, con);
InputStream responseBody = readResponseBody(config, con);
return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
}
//把序列化对象输出到HttpURLConnection去
protected void writeRequestBody(
HttpInvokerClientConfiguration config, HttpURLConnection con, ByteArrayOutputStream baos)
throws IOException {
baos.writeTo(con.getOutputStream());
}
//为使用HttpURLConnection完成对象序列化,需要进行一系列的配置
//比如配置请求方式为post,请求属性等等
protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException {
con.setDoOutput(true);
con.setRequestMethod(HTTP_METHOD_POST);
con.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, getContentType());
con.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, Integer.toString(contentLength));
LocaleContext locale = LocaleContextHolder.getLocaleContext();
if (locale != null) {
con.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, StringUtils.toLanguageTag(locale.getLocale()));
}
if (isAcceptGzipEncoding()) {
con.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
}
//获得HTTP响应的IO流
protected InputStream readResponseBody(HttpInvokerClientConfiguration config, HttpURLConnection con)
throws IOException {
//如果是通过gzip压缩,那么需要先解压
if (isGzipResponse(con)) {
// GZIP response found - need to unzip.
return new GZIPInputStream(con.getInputStream());
}
else {
// Plain response found.
// 正常的HTTP响应输出
return con.getInputStream();
}
}
HTTP调用器服务器端的实现
在服务器端使用Spring HTTP远端调用,需要配置HttpInvokerServiceExporter,作为远端服务的服务导出器,来接收HTTP服务请求。在通过HTTP请求,得到客户端传过来的RemoteInvocation对象以后,就可以进行服务方法的调用了。服务调用需要的基本信息,都封装在RemoteInvocation对象中。这个服务调用过程,是由invokeAndCreateResult方法来实现的,如RemoteInvocationSerializingExporter的invoke实现所示:
- protected Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- if (logger.isTraceEnabled()) {
- logger.trace("Executing " + invocation);
- }
- try {//调用RemoteInvocationExecutor,这个执行器是DefaultRemoteInvocationExecutor
- return getRemoteInvocationExecutor().invoke(invocation, targetObject);
- }
- catch (NoSuchMethodException ex) {
- if (logger.isDebugEnabled()) {
- logger.warn("Could not find target method for " + invocation, ex);
- }
- throw ex;
- }
- catch (IllegalAccessException ex) {
- if (logger.isDebugEnabled()) {
- logger.warn("Could not access target method for " + invocation, ex);
- }
- throw ex;
- }
- catch (InvocationTargetException ex) {
- if (logger.isDebugEnabled()) {
- logger.debug("Target method failed for " + invocation, ex.getTargetException());
- }
- throw ex;
- }
- }
protected Object invoke(RemoteInvocation invocation, Object targetObject)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
if (logger.isTraceEnabled()) {
logger.trace("Executing " + invocation);
}
try {//调用RemoteInvocationExecutor,这个执行器是DefaultRemoteInvocationExecutor
return getRemoteInvocationExecutor().invoke(invocation, targetObject);
}
catch (NoSuchMethodException ex) {
if (logger.isDebugEnabled()) {
logger.warn("Could not find target method for " + invocation, ex);
}
throw ex;
}
catch (IllegalAccessException ex) {
if (logger.isDebugEnabled()) {
logger.warn("Could not access target method for " + invocation, ex);
}
throw ex;
}
catch (InvocationTargetException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Target method failed for " + invocation, ex.getTargetException());
}
throw ex;
}
}
看到的invoke方法封装了服务器端调用的主体,这个invoke方法在HttpInvokerServiceExporter的基类RemoteInvocationSerializingExporter中实现,服务对象的方法调用完成之后,会把调用结果,通过HTTP响应和对象序列化,传给HTTP调用器客户端,从而完成整个HTTP调用器的远端调用过程,如以下代码所示:
- protected void writeRemoteInvocationResult(
- HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result)
- throws IOException {
- //设置Response的ContentType属性,设置为application/x-java-serialized-object
- response.setContentType(getContentType());
- writeRemoteInvocationResult(request, response, result, response.getOutputStream());
- }
- //输出到HTTP的Response,然后把Response关闭
- protected void writeRemoteInvocationResult(
- HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result, OutputStream os)
- throws IOException {
- ObjectOutputStream oos = createObjectOutputStream(decorateOutputStream(request, response, os));
- try {
- doWriteRemoteInvocationResult(result, oos);
- oos.flush();
- }
- finally {
- oos.close();
- }
- }
protected void writeRemoteInvocationResult(
HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result)
throws IOException {
//设置Response的ContentType属性,设置为application/x-java-serialized-object
response.setContentType(getContentType());
writeRemoteInvocationResult(request, response, result, response.getOutputStream());
}
//输出到HTTP的Response,然后把Response关闭
protected void writeRemoteInvocationResult(
HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result, OutputStream os)
throws IOException {
ObjectOutputStream oos = createObjectOutputStream(decorateOutputStream(request, response, os));
try {
doWriteRemoteInvocationResult(result, oos);
oos.flush();
}
finally {
oos.close();
}
}
经过这一系列的处理过程,服务执行结果对象又回到了HTTP的远端调用客户端。在客户端从HTTP响应读取对象之后,它把这个看起来像是在本地实现,其实是由远端服务对象完成的调用结果,交给发起远端调用的客户端调用方法,从而最终完成整个远端调用的过程。这个过程很有特点,它使用了HTTP的请求和响应作为通信通道,在这个通信通道里面,并没有再做进一步的附加的通信协议的封装,而且,在这个处理过程中,使用的都是Java和Spring框架已有的特性,比如,通过IoC的配置,以及代理对象拦截器的封装处理,再加Java的序列化和反序列化,以及在服务器端的Spring MVC框架的使用,通过这些已有的技术实现,让使用者感觉,它的实现风格非常的简洁轻快,整个代码实现,阅读起来,也让人感到非常的赏心悦目。
发表评论
-
Spring Framework 开发参考手册
2011-09-02 16:15 1423http://www.html.org.cn/books/sp ... -
相关知识和链接
2011-09-01 15:21 1210《spring攻略》译员博客http://digitalson ... -
spring简述
2011-08-31 16:25 1231背景 Rod Johnson在2002年编著的《Expert ... -
传智播客_spring_PPT_黎活明
2011-08-05 16:44 0传智播客_spring_PPT_黎活明.ppt -
spring 中的singleton和ClassLoader中的单例
2011-08-03 15:50 2504http://www.iteye.com/topic/7186 ... -
Spring AOP原理及拦截器
2011-07-11 14:25 2145原理AOP(Aspect Oriented Progr ... -
Spring AOP: Spring之面向方面编程
2011-07-11 14:12 5915.1. 概念 ... -
AOP
2011-07-11 14:10 1421What is AOP?AOP即Aspect-Orie ... -
Spring的组件自动扫描机制
2011-07-06 10:06 2277Spring将所有的bean都纳入到IOC中创建、管理和维护。 ... -
Spring事物笔记
2011-06-14 23:01 1761/**什么异常时才回滚**/ Spring事务策略由Pl ... -
Spring in Action 学习笔记—第六章 远程调用
2010-12-24 10:09 1781远程调用是客户端应用 ... -
浅谈Spring事务隔离级别
2010-11-02 16:05 1155本文将介绍Spring事务隔 ... -
Spring事务的传播行为和隔离级别
2010-11-02 15:51 1370Spring中事务的定义:一、Propagation : ... -
spring aop 面向切面编程 如何来做一个强大的日志记录功能
2010-07-08 16:11 3566这个东西怎么做:spring aop 面向切面编程 如何来做一 ... -
Spring中单例bean访问非单例bean的第一种方式:方法注入
2010-07-08 15:20 2726方法注入在Spring中是很少用的,主要应用是, ... -
关于spring声明式事务管理异常处理的测试和小结
2010-07-08 10:51 1296关于spring事务管理以及异常处理的帖子,本论坛争论颇多,各 ... -
Spring源代码解析(一):IOC容器(1)
2010-07-01 11:00 1208ss -
spring ApplicationContext的实现
2010-07-01 10:37 1486spring为ApplicationContext提供的3 ... -
使用web.xml方式加载Spring时,获取Spring context的两种方式:
2010-06-25 14:10 15991、servlet方式加载时: 【web .xml】 ... -
Spring 框架的设计理念与设计模式分析(2)
2010-06-18 09:59 1592如何创建 Bean 实例并构建 Bean 的关系网 下面 ...
相关推荐
Spring技术内幕:深入解析Spring架构与设计原理(第2部分) 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔!Java开发者社区和Spring...
Spring技术内幕 深入解析Spring架构与设计原理1(完整清晰版),一共两部分,这是第一部分 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自...
Spring技术内幕 深入解析Spring架构与设计原理1(完整清晰版),一共两部分,这是第一部分 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自...
Spring技术内幕 深入解析Spring架构与设计原理1(完整清晰版),一共两部分,这是第一部分 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自...
深入解析spring架构原理与设计思想,探究spring成功的奥秘。 揭开spring源代码的神秘面纱,展示系统阅读开源软件源代码的方法和秘诀。 掌握spring的架构原理与设计思想真的能让开发者如虎添翼吗? ioc容器...
深入解析spring架构原理与设计思想,探究spring成功的奥秘。 揭开spring源代码的神秘面纱,展示系统阅读开源软件源代码的方法和秘诀。 掌握spring的架构原理与设计思想真的能让开发者如虎添翼吗? ioc...
Spring技术内幕 深入解析Spring架构与设计原理1(完整清晰版),一共两部分,这是第一部分 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自...
Spring技术内幕 深入解析Spring架构与设计原理1(完整清晰版),一共两部分,这是第一部分 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自...
, 深入解析Spring架构原理与设计思想,探究Spring成功的奥秘。, 揭开Spring源代码的神秘面纱,展示系统阅读开源软件源代码的方法和秘诀。, 如果你也在思考下面的问题,本书也许就是你想要的:, 掌握Spring的架构原理...
Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源...
适合有spring框架的javaEE平台,出自spring的HttpInvokerServiceExporter导出器,依赖Spring.jar
spirng远程调用可运行简单实例。包含所需所有jar spring-*-3.*.RELEASE.jar aopalliance.jar等。
Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源...
Spring远程调用使用http方式,将server和client直接部署后,进入http://localhost/HttpClientSpringRMIClient/即可
普通javaweb项目调用springCloud接口(超级实用,很详细)但是要注意的事一定要对springboot和springcloud的有所了解,不然的话你也是看不懂的,大家一起努力共同学习
Spring为各种远程访问技术提供集成工具类。Spring远程访问通过使用普通POJOs,能更容易的开发远程访问服务。目前,Spring远程访问的主要技术如下: 1. 远程调用RMI(Remote Method Invocation): 通过使用 ...
使用 spring 的 httpinvoker 进行远程调用
上传的这个microservicecloud工程的主要使用了SpringCloud的5大技术栈做了一个微服务架构案例,涉及到Eureka集群的配置、Ribbon的自定义负载均衡、Feign的声明式接口调用、Hystrix的服务熔断和降级、Zuul的Api ...
上文我们利用Spring rmi实现了Spring的远程访问(Spring 实现远程访问详解——rmi),本文主要讲解利用HttpInvoke实现远程访问。 Spring httpInvoker使用标准java序列化机制,通过Http暴露业务服务。如果你的参数和...