【spring源码学习】spring的远程调用实现源码分析
【一】spring的远程调用提供的基础类
(1)org.springframework.remoting.support.RemotingSupport
===>spring提供实现的远程调用客户端实现的基础类
===>例子:org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
org.springframework.remoting.caucho.HessianProxyFactoryBean
(2)org.springframework.remoting.support.RemoteExporter
===>spring提供实现的远程调用服务端实现的基础类
===>例子:org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
org.springframework.remoting.caucho.HessianServiceExporter
【二】spring的远程调用基于Http协议实现的封装,以该例子分析远程调用实现原理和源码分析
(1)HttpInvokerProxyFactoryBean 客户端的实现
===>HttpInvokerProxyFactoryBean类是一个FactoryBean的实现接口,注入IOC后,未来向IOC申请bean,其实返回的是getObject()方法返回的实现.在实例化阶段会调用afterPropertiesSet() 进行初始化.根据配置创建代理对象.
===>在getObject()方法中,是完成了一个代理对象的封装.代理增强的配置:serviceUrl和serviceInterface.一个配置的请求url,一个配置的要代理的接口.
===>该代理对象的增强实现就是org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor的invoke(MethodInvocation methodInvocation) 方法.也就是HttpInvokerProxyFactoryBean的父类.将来会作为增强实现,加入到代理对象中.
===>未来发起调用.其实底层是代理对象的拦截器,也就是HttpInvokerClientInterceptor调用invoke方法.将数据类序列化,利用serviceUrl向远程调用接口发送http请求.
(2)HttpInvokerServiceExporter 服务端的实现
===>HttpInvokerServiceExporter类是org.springframework.web.HttpRequestHandler的实现类.该类在实例化的时候,会调用afterPropertiesSet()初始化.如果配置有拦截器(即属性Object[] interceptors),则需要为实际调用的facadeImpl创建代理对象.
===>该类将来会作为一个bean加入到org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping中.
===>当客户端发送请求,进入DispatcherServlet中,从beanNameUrlHandlerMapping中获取该bean,再用该bean找到org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.该HttpRequestHandlerAdapter会判断bean是否是HttpRequestHandler的实现类的实例.如果是,调用HttpInvokerServiceExporter类的handleRequest()方法去实现真正facadeImpl的调用
===>在配置HttpInvokerServiceExporter的时候的配置
>需要配置url,将来作为和客户端的请求地址的匹配.
>需要配置所代理的接口.
>需要配置真正的实现类的实例,该实例也可能在实例化bean的时候如果有aop配置,其实也是一个代理对象.这就是多层代理.多层代理在技术层面是允许的.
(3)BeanNameUrlHandlerMapping,HttpRequestHandlerAdapter是如何加载进IOC容器中的?
===>初始化DispatcherServlet的时候,最后会调用initStrategies(ApplicationContext context)方法,内部有初始化的方法,从配置文件里加载,然后编码方式加入IOC容器.从DispatcherServlet.properties文件中获取相应的配置.
===>BeanNameUrlHandlerMapping是ApplicationContextAware 接口的实现类.在IOC容器实例化阶段,会调用setApplicationContext(ApplicationContext context)进行映射配置.
【三】以HttpInvoker为例子写一个服务端和客户端
(1)facade接口
package com.mobile.thinks.user.facade; import com.mobile.thinks.user.dto.UserDTO;
/**
* 接口
* @author sxf
*
*/
public interface UserFacade { public UserDTO updateUserByUserDTO(UserDTO userDTO);
}
(2)facade接口的参数
package com.mobile.thinks.user.dto;
import java.io.Serializable;
public class UserDTO implements Serializable {
private String id;
private String name;
private String address;
private int age;
private String sex;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
(3)facade实现
package com.mobile.thinks.user.facade.impl; import org.springframework.stereotype.Component; import com.mobile.thinks.user.dto.UserDTO;
import com.mobile.thinks.user.facade.UserFacade; @Component(value="userFacade")
public class UserFacadeImpl implements UserFacade{ @Override
public UserDTO updateUserByUserDTO(UserDTO userDTO) {
System.out.println("传过来的参数ID====>"+userDTO.getId());
System.out.println("传过来的参数Name===>"+userDTO.getName());
System.out.println("传过来的参数Address===>"+userDTO.getAddress());
System.out.println("传过来的参数Age===>"+userDTO.getAge());
System.out.println("传过来的参数Sex===>"+userDTO.getSex()); UserDTO dto=new UserDTO();
dto.setId("abcdefghijklmnopqrstuvwxyz");
dto.setName("尚晓飞");
dto.setSex("男");
dto.setAge(28);
dto.setAddress("三门峡");
return dto;
} }
(4)客户端配置实现
<bean id="userFacade" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl"><value>http://localhost:8080/thinks-webservice/http/userFacade</value></property>
<property name="serviceInterface"><value>com.mobile.thinks.user.facade.UserFacade</value></property>
</bean>
(5)服务端配置实现
<bean name="/http/userFacade" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="serviceInterface"><value>com.mobile.thinks.user.facade.UserFacade</value></property>
<property name="service" ref="userFacade" />
</bean>
【spring源码学习】spring的远程调用实现源码分析的更多相关文章
- Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析
目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...
- spring源码学习——spring整体架构和设计理念
Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的java ...
- spring cloud eureka + feign,api远程调用
网上教程不少,有些就是复制粘贴,不结合实际生产. eureka不再阐述. 一般正常开发会有多个工程,且多个module. 我的习惯是: eureka server.权限.config.gateway ...
- Spring系列:学习Spring的资源和讨论
1) 阅读<spring in action 4th edition>,这样可以对的spring可以做什么事情有个基本了解: 2) 阅读spring.io官网提供的各种reference, ...
- Java并发包源码学习系列:线程池ThreadPoolExecutor源码解析
目录 ThreadPoolExecutor概述 线程池解决的优点 线程池处理流程 创建线程池 重要常量及字段 线程池的五种状态及转换 ThreadPoolExecutor构造参数及参数意义 Work类 ...
- Java并发包源码学习系列:同步组件CountDownLatch源码解析
目录 CountDownLatch概述 使用案例与基本思路 类图与基本结构 void await() boolean await(long timeout, TimeUnit unit) void c ...
- Java并发包源码学习系列:同步组件CyclicBarrier源码解析
目录 CyclicBarrier概述 案例学习 类图结构及重要字段 内部类Generation及相关方法 void reset() void breakBarrier() void nextGener ...
- Java并发包源码学习系列:同步组件Semaphore源码解析
目录 Semaphore概述及案例学习 类图结构及重要字段 void acquire() 非公平 公平策略 void acquire(int permits) void acquireUninterr ...
- Qt Creator 源码学习笔记04,多插件实现原理分析
阅读本文大概需要 8 分钟 插件听上去很高大上,实际上就是一个个动态库,动态库在不同平台下后缀名不一样,比如在 Windows下以.dll结尾,Linux 下以.so结尾 开发插件其实就是开发一个动态 ...
随机推荐
- sublime text3 破解, 中文乱码支持, 设置
1. 激活 菜单: Help -> Enter License, 弹出对话框输入激活码确认(Use License):如下图:. 激活码: ----- BEGIN LICENSE ----- A ...
- 启动工程Ehcache报错
缓存组建用的Ehcache,在启动的时候报了下面的错误,虽然不影响使用,看着还是有点碍眼: DEBUG net.sf.ehcache.util.UpdateChecker - Update che ...
- codevs.cn 2776寻找代表元 最大流解法
网址:http://codevs.cn/problem/2776/ 题目大意: n个社团,m个人,每个社团可以有一个人担任代表,每个人可以担任多个代表,问最多有多少人是代表. 思路:可以建一个图,然后 ...
- tar 解压命令学习与总结
tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个 ...
- LeetCode——Reverse String
LeetCode--Reverse String Question Write a function that takes a string as input and returns the stri ...
- MVC viewbag & viewdata
弱类型:ViewData[""] 动态型:ViewBag dynamic ViewData 是字典型的(Dictionary),ViewBag 不再是字典的键值对结构,而是dyna ...
- Eclipse 添加JSP模板
0.环境 Eclipse IDE for Java EE Developers (4.3.2) win8.1系统 1.原因 Eclipse自带新建JSP为: <%@ page language= ...
- ThinkPad.E440_FN键反了
1.一直不知道,为何我的 FN键反了(Fn+F1 才是F1的功能),想改过来.查到是 BIOS中改,但是 BIOS里面没有 那些个修改的选项,于是 还原了BIOS的设置,于是出问题了... 2.问题1 ...
- python学习笔记(arange函数与linspace函数)
上一篇提及到matplotlib模块.其中会涉及到numpy模块科学计数 这里总结两个数组生成函数 arange 与 linspace: #!/usr/bin/env python # -*- cod ...
- MVVM4
原地址(内容更丰富):http://www.cnblogs.com/888h/category/269092.html MVVM架构的简单解析 图1 View.ViewModel.Model之间的 ...