【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>

时间: 2024-10-11 00:17:48

【spring源码学习】spring的远程调用实现源码分析的相关文章

Swoole源码学习记录(十五)——Timer模块分析

swoole版本:1.7.7-stable Github地址:点此查看 1.Timer 1.1.swTimer_interval_node 声明: // swoole.h 1045-1050h typedef struct _swTimer_interval_node { struct _swTimerList_node *next, *prev; struct timeval lasttime; uint32_t interval; } swTimer_interval_node; 成员 说明

Spring RestTemplate实现服务间的远程调用完整代码示例

父pom: 服务提供方 pom: provider配置文件: provider启动类: provider实体类: provider Mapper: 内置了增删改查的方法 provider Service: 屏蔽报错: provider Controller: 服务调用方 pom: Consumer启动类: Consumer实体类: Consumer的Controller: 统一管理启动类: 可以直接在面板启动~ 测试调用: 原文地址:https://www.cnblogs.com/niwotax

OpenFire源码学习之二十七:Smack源码解析

Smack Smack是一个用于和XMPP服务器通信的类库,由此可以实现即时通讯和聊天.Android中开发通讯APP也可以使用这个包.关于smack的中文开发文档,目前网上也有很多. 下面本,将从源码中分析smack的几个案例. 连接 关于smack的Connection是连接XMPP服务器的默认实现.他有两个构造函数,一个是XMPPConecttion(String) 接收服务器地址名的参数.这个是默认的比较常用的构造方法. l 查找一个DNS的SRC,首先需要找到它精确的服务器地址和端口默

ejb学习1-helloword,ejb远程调用

环境 win7 myeclipse10 jboss4.0.5 创建第一个ejb项目 1. new EJB project 2.创建一个 sessionbean 接口 3.编写ejb接口 package com.mo.ejb; import javax.ejb.Stateless; @Stateless public interface HelloWorld { String sayHello(String name); } 4.实现接口 package com.mo.ejb; public cl

JDK源码学习阅读-Integer类中的parseInt方法分析(转)

方法原型: public static int parseInt(String s,int radix): 输入:s表示待转换的字符串:radix表示需要转换成几进制的整数: 输出:返回一个32位整数. 算法流程图: JDK中的代码实现: 1 /** 2 * 字符串转换成整数 3 * @param s 待转换字符串 4 * @param radix 进制 5 * @return 6 */ 7 public static int parseInt(String s,int radix){ 8 //

猫猫学iOS之二维码学习,快速打开相机读取二维码

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 上一篇文章写了怎么生成二维码,这儿就说说怎么读取吧,反正也很简单,iOS封装的太强大了 步骤呢就是这样: 读取二维码需要导入AVFoundation框架#import <AVFoundation/AVFoundation.h> 1:利用摄像头识别二维码中的内容(模拟器不行). 2:输入(摄像头). 3:由会话将摄像头采集到的二维码图像转换成字符串数据. 4:输

Spring HttpIvoker实现Java的远程调用

Spring HttpInvoker一种JAVA远程方法调用框架实现,使用的是HTTP协议,允许穿透防火墙,使用JAVA系列化方式,但仅限于Spring应用之间使用,即调用者与被调用者都必须是使用Spring框架的应用.基本原理如下: 在server端,springAOC管理着controller(bean),并暴露出远程调用的接口.在Client端,借助spring产生一个代理对象,通过代理对象实现与服务端的交互. 服务器端配置 1. 加入jar包 2. 在.xml中配置spring远程调用的

Spring远程调用HTTP invoker

前言 在日常的工作中,会有客户端调用远程服务端接口的需求,这样的需求实现,在网上查到有像RMI.hessian.Burlap等,下文给出HTTP Invoker实现远程调用,他不用使用者考虑对象序列化的问题,对使用者,非常的友好. 下面介绍在Spring中配置HTTP Invoker实现远程调用.分为服务提供方和服务消费方两部分. 案例 服务提供方 1.定义一个接口和接口实现类,服务提供方提供. WelcomeService.java package com.aaron.service; imp

spring事务管理学习

spring事务管理学习 spring的事务管理和mysql自己的事务之间的区别 参考很好介绍事务异常回滚的文章 MyBatis+Spring 事务管理 spring中的事务回滚例子 这篇文章讲解了@Transaction注解事务和<tx:tags>方式的声明式事务的优缺点 Spring3核心技术之事务管理机制 这篇文章介绍了spring 事务管理的源码 spring源码分析之——spring 事务管理实现方式 揭开Spring事务处理 一般而言dao层是对单张表进行的操作,而service层