【一】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的远程调用实现源码分析的更多相关文章

  1. Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析

    目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...

  2. spring源码学习——spring整体架构和设计理念

    Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的java ...

  3. spring cloud eureka + feign,api远程调用

    网上教程不少,有些就是复制粘贴,不结合实际生产. eureka不再阐述. 一般正常开发会有多个工程,且多个module. 我的习惯是: eureka server.权限.config.gateway ...

  4. Spring系列:学习Spring的资源和讨论

    1) 阅读<spring in action 4th edition>,这样可以对的spring可以做什么事情有个基本了解: 2) 阅读spring.io官网提供的各种reference, ...

  5. Java并发包源码学习系列:线程池ThreadPoolExecutor源码解析

    目录 ThreadPoolExecutor概述 线程池解决的优点 线程池处理流程 创建线程池 重要常量及字段 线程池的五种状态及转换 ThreadPoolExecutor构造参数及参数意义 Work类 ...

  6. Java并发包源码学习系列:同步组件CountDownLatch源码解析

    目录 CountDownLatch概述 使用案例与基本思路 类图与基本结构 void await() boolean await(long timeout, TimeUnit unit) void c ...

  7. Java并发包源码学习系列:同步组件CyclicBarrier源码解析

    目录 CyclicBarrier概述 案例学习 类图结构及重要字段 内部类Generation及相关方法 void reset() void breakBarrier() void nextGener ...

  8. Java并发包源码学习系列:同步组件Semaphore源码解析

    目录 Semaphore概述及案例学习 类图结构及重要字段 void acquire() 非公平 公平策略 void acquire(int permits) void acquireUninterr ...

  9. Qt Creator 源码学习笔记04,多插件实现原理分析

    阅读本文大概需要 8 分钟 插件听上去很高大上,实际上就是一个个动态库,动态库在不同平台下后缀名不一样,比如在 Windows下以.dll结尾,Linux 下以.so结尾 开发插件其实就是开发一个动态 ...

随机推荐

  1. spring配置中classpath: 与classpath*:的区别

    classpath和classpath*区别:  classpath:只会到你的class路径中查找找文件. classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找 ...

  2. LeetCode——Next Greater Element I

    LeetCode--Next Greater Element I Question You are given two arrays (without duplicates) nums1 and nu ...

  3. Mongo, Express, Angular, Node-- MEAN Stack搭建

    前言 作为一个从后端转全栈的码农,我一直使用express,jade & bootstrap, jquery的组合.重复了几次相同的工作后,看到网上开始流行MEAN Stack,于是也对其研究 ...

  4. .NET Framework(CLI,CLS,CTS,CLR,FCL,BCL)

    最下层蓝色部分是.NET Framework的基础,也是所有应用软件的基础..NET Framework不是凭空出来的,实际上API,COM+,和一些相关驱动依然是它的基石..NET Framewor ...

  5. CentOS下安装mysql及配置使用

    最近一直使用的是CentOS,平时用的最多的数据库是Sql Server,对于mysql还停留在上学的时候,早已忘得一干二净,写这篇内容目的是,重新学习如何安装使用mysql. 一.安装mysql 操 ...

  6. WCF简单学习

    前两天学习了WCF的一些基础东西,好像不怎么用,但是学习一下还是有助自己增长知识滴.既然是学习就先偷一下别人的概念基础.wcf中有一个ABC的概念,就是第一: "A" 是地址,就是 ...

  7. python标准日志模块logging使用

    python的标准库里的日志系统从Python2.3开始支持.只要import logging这个模块即可使用.如果你想开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件,只要这样使用: ...

  8. linux中的kill命令

    一. 定义 kill命令用来删除执行中的程序或工作.kill可将指定的信息送至程序.预设的信息为SIGTERM(15),可将指定程序终止.若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除 ...

  9. SimpleDateFormat函数语法

    SimpleDateFormat函数语法:         G 年代标志符         y 年         M 月         d 日         h 时 在上午或下午 (1~12)  ...

  10. 完全卸载gitlab

    完全卸载删除gitlab 2017年5月29日 wuhao 暂无评论 4,089次浏览   完全卸载删除gitlab 1.停止gitlab   1 gitlab-ctl stop 2.卸载gitlab ...