【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);
}

View Code

(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;
    }

}

View Code

(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;
    }

}

View Code

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

View Code

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

View Code

 

时间: 2024-10-26 06:46:14

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

【spring源码学习】spring的AOP面向切面编程的实现解析

一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口  =>org.springframework.aop.BeforeAdvice   org.springframework.aop.MethodBeforeAdvice  =>org.springframework.aop.AfterAdvice   org.springframework.aop.After

【spring源码学习】spring的事务管理的源码解析

[一]spring事务管理(1)spring的事务管理,是基于aop动态代理实现的.对目标对象生成代理对象,加入事务管理的核心拦截器==>org.springframework.transaction.interceptor.TransactionInterceptor.===>spring事务管理的核心拦截器===>需要配置的数据项:事务管理机制配置属性的查找类transactionAttributeSource,事务管理的核心处理器PlatformTransactionManager

【spring源码学习】spring的IOC容器在初始化bean过程

[一]初始化IOC的bean的时候Spring会执行的一些回调方法 (1)spring bean创建的前置处理 =>ApplicationContextAwareProcessor 在创建bean的时候调用 bean.setEnvironment(this.applicationContext.getEnvironment()) bean.setEmbeddedValueResolver(new EmbeddedValueResolver(this.applicationContext.getB

spring源码学习之:xml标签扩展配置例子

在很多情况下,我们需要为系统提供可配置化支持,简单的做法可以直接基于Spring的标准Bean来配置,但配置较为复杂或者需要更多丰富控制的 时候,会显得非常笨拙.一般的做法会用原生态的方式去解析定义好的xml文件,然后转化为配置对象,这种方式当然可以解决所有问题,但实现起来比较繁琐, 特别是是在配置非常复杂的时候,解析工作是一个不得不考虑的负担.Spring提供了可扩展Schema的支持,这是一个不错的折中方案,完成一个自定义 配置一般需要以下步骤: 设计配置属性和JavaBean 编写XSD文

spring源码系列(一)sring源码编译 spring源码下载 spring源码阅读

想对spring框架进行深入的学习一下,看看源代码,提升和沉淀下自己,工欲善其事必先利其器,还是先搭建环境吧. 环境搭建 sping源码之前是svn管理,现在已经迁移到了github中了,新版本基于gradle构建项目.所以构建sping源码环境必须先安装github以及Gradle. 当然了如果不想安装github客户端可以直接去git下载项目:spring中git地址https://github.com/spring-projects/spring-framework 安装github 首先

Openstack Nova 源码分析 — RPC 远程调用过程

目录 目录 Nova Project Services Project 的程序入口 setuppy Nova中RPC远程过程调用 nova-compute RPC API的实现 novacomputemanager 模块 最后 Nova Project Services nova-api:捕获novaclient发送过来的HTTP请求,并且将它转换为AMQP消息,通过Queue来与别的services通信. nova-conductor:为数据库访问提供了一层安全保障. NOTE:除了nova-

Spring远程调用返回数据异常

问题描述 最近做一个项目,需要从his同步数据同样的程序,可以从SQLServer同步数据但换成Oracle后,测试代码出现图片中的异常最后找出问题,Oracle返回数据接近五万,然后就出现图片中异常,给语句加上条件,返回少量数据,可以正常返回.换一个语句,数据三万多,可以正常返回.所以,当远程调用需要返回数据时,数据太多就会出现异常 解决方案

Hadoop源码学习:RPC

Hadoop源码学习:RPC Hadoop RPC使用java NIO编写,达到高性能,轻量级,可控性. 主要分为四层:序列化层,函数调用层,网络传输层,服务器端处理框架 序列化层:实现Writable接口 函数调用层:java反射机制和动态代理实现函数调用 网络传输层:使用Socket机制 服务器端处理框架:基于Reactor设计模式的事件驱动I/O模型 如何使用Hadoop RPC: RPC Server: 1.定义一个协议,实现VersionedProtocol接口, public int

刚开始学习spring 有一点小问题 希望能得到高手解答

问题描述 刚开始学习spring 有一点小问题 希望能得到高手解答 ?下面这几段代码中有一个地方不是很理解,希望能得到指点 UserServiceTest.java @Test public void testAdd() throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); UserService service = (UserService)ctx.ge