【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结尾 开发插件其实就是开发一个动态 ...
随机推荐
- spring配置中classpath: 与classpath*:的区别
classpath和classpath*区别: classpath:只会到你的class路径中查找找文件. classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找 ...
- LeetCode——Next Greater Element I
LeetCode--Next Greater Element I Question You are given two arrays (without duplicates) nums1 and nu ...
- Mongo, Express, Angular, Node-- MEAN Stack搭建
前言 作为一个从后端转全栈的码农,我一直使用express,jade & bootstrap, jquery的组合.重复了几次相同的工作后,看到网上开始流行MEAN Stack,于是也对其研究 ...
- .NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)
最下层蓝色部分是.NET Framework的基础,也是所有应用软件的基础..NET Framework不是凭空出来的,实际上API,COM+,和一些相关驱动依然是它的基石..NET Framewor ...
- CentOS下安装mysql及配置使用
最近一直使用的是CentOS,平时用的最多的数据库是Sql Server,对于mysql还停留在上学的时候,早已忘得一干二净,写这篇内容目的是,重新学习如何安装使用mysql. 一.安装mysql 操 ...
- WCF简单学习
前两天学习了WCF的一些基础东西,好像不怎么用,但是学习一下还是有助自己增长知识滴.既然是学习就先偷一下别人的概念基础.wcf中有一个ABC的概念,就是第一: "A" 是地址,就是 ...
- python标准日志模块logging使用
python的标准库里的日志系统从Python2.3开始支持.只要import logging这个模块即可使用.如果你想开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件,只要这样使用: ...
- linux中的kill命令
一. 定义 kill命令用来删除执行中的程序或工作.kill可将指定的信息送至程序.预设的信息为SIGTERM(15),可将指定程序终止.若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除 ...
- SimpleDateFormat函数语法
SimpleDateFormat函数语法: G 年代标志符 y 年 M 月 d 日 h 时 在上午或下午 (1~12) ...
- 完全卸载gitlab
完全卸载删除gitlab 2017年5月29日 wuhao 暂无评论 4,089次浏览 完全卸载删除gitlab 1.停止gitlab 1 gitlab-ctl stop 2.卸载gitlab ...