文档章节

spring与thrift集成

penngo
 penngo
发布于 2015/08/14 11:15
字数 833
阅读 4043
收藏 8
点赞 0
评论 0

spring与thrift集成,可以使服务调用和发布更方便。

本文代码是在上篇基础上改进,部分代码介绍请参考上一篇Thrift的java和php数据交互(http://my.oschina.net/penngo/blog/489311)

服务器端spring配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
				http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"
	default-lazy-init="false">

	<!-- 登录服务 -->
	<bean id="loginServiceImpl" class="com.penngo.LoginServiceImpl" />
	<!-- 注册服务 -->
	<bean id="registerServiceImpl" class="com.penngo.RegisterServiceImpl" />
	
	<bean id="thriftServer" class="com.penngo.main.SpringServer" init-method="init" destroy-method="close">
	    <property name="port" value="7911" />
	    <property name="serviceList">  
	        <map>
                <entry key = "LoginService">
                    <ref bean = "loginServiceImpl" />
                </entry>
                <entry key = "RegisterService">
                    <ref bean = "registerServiceImpl" />
                </entry>
            </map>
        </property> 
	</bean>
</beans>

服务发布实现

package com.penngo.main;

import java.lang.instrument.IllegalClassFormatException;
import java.lang.reflect.Constructor;
import java.util.Map;

import org.apache.thrift.TMultiplexedProcessor;
import org.apache.thrift.TProcessor;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class SpringServer {
	private Map<String, Object> serviceList;
	private int port;
	private TServerSocket serverTransport;
	
	public void setServiceList(Map<String, Object> serviceList) {
		this.serviceList = serviceList;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public void init(){
		try {
			serverTransport = new TServerSocket(port);
			TMultiplexedProcessor mprocessor = new TMultiplexedProcessor();
			for(Map.Entry<String, Object> entry : serviceList.entrySet()){
				Object obj = entry.getValue();
				Class<?> serviceClass = obj.getClass();
				// 获取实现类接口
				Class<?>[] interfaces = serviceClass.getInterfaces();
				TProcessor processor = null;
				String serviceName = null;
				for(Class<?> clazz:interfaces){
					System.out.println("ThriftServer=========" + clazz.getSimpleName());
					String className = clazz.getEnclosingClass().getSimpleName();
					serviceName = clazz.getEnclosingClass().getName();
					System.out.println("serviceName=========" + serviceName + " " + className);
					String pname = serviceName + "$Processor";
					try {
						ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
						Class<?> pclass = classLoader.loadClass(pname);
						if (!TProcessor.class.isAssignableFrom(pclass)) {
							continue;
						}
						Constructor<?> constructor = pclass.getConstructor(clazz);
						processor = (TProcessor) constructor.newInstance(obj);
						System.out.println("processor=========" + processor.getClass().getSimpleName());
						mprocessor.registerProcessor(className, processor);
						break;
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				if (processor == null) {
					throw new IllegalClassFormatException("service-class should implements Iface");
				}
				
			}
			TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(
			serverTransport).processor(mprocessor));
			System.out.println("Starting server on port 7911 ...");
			server.serve();

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void close(){
		serverTransport.close();
	}
	
	public static void main(String[] args){
		try {
			new ClassPathXmlApplicationContext("classpath:spring-context-thrift-server.xml");
			//Thread.sleep(3000000);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

客户端spring配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
				http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"
	default-lazy-init="false">

	<bean id="thriftServer" class="com.penngo.main.SpringClient" init-method="init" destroy-method="close">
	    <property name="port" value="7911" />
	    <property name="serviceMap">  
	        <map>
                <entry key = "LoginService">
                    <value>com.penngo.LoginService</value>
                </entry>
                <entry key = "RegisterService">
                    <value>com.penngo.RegisterService</value>
                </entry>
            </map>
        </property> 
	</bean>
</beans>

客户端调用例子

package com.penngo.main;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TMultiplexedProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.penngo.LoginService;
import com.penngo.RegisterService;
import com.penngo.User;

public class SpringClient {
	private int port;
	private Map<String, String> serviceMap;
	private Map<String, Object> clientMap;
	private TTransport transport;
	public void setPort(int port) {
		this.port = port;
	}

	public void setServiceMap(Map<String, String> serviceMap) {
		this.serviceMap = serviceMap;
	}



	public Object getClient(String name){
		return clientMap.get(name);
	}
	
	public void init(){
		clientMap = new HashMap<String, Object>();
		try {
			transport = new TSocket("localhost", port);
			TProtocol protocol = new TBinaryProtocol(transport);
			for(Map.Entry<String, String> entry : serviceMap.entrySet()){
				String obj = entry.getValue();
				System.out.println(entry.getKey() + " " + entry.getValue());
				TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol,
						entry.getKey());
				ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
				Class<?> objectClass = classLoader.loadClass(obj + "$Client");

				Constructor<?> stor = objectClass.getDeclaredConstructor(TProtocol.class);
				Object client = stor.newInstance(mp);
				clientMap.put(entry.getKey(), client);
			}

			transport.open();

		} catch (Exception x) {
			x.printStackTrace();
		}
	}
	public void close(){
		transport.close();
	}
	
	public static void main(String[] args){
		try {
			ApplicationContext context = new ClassPathXmlApplicationContext("spring-context-thrift-client.xml");
			SpringClient springClient = (SpringClient) context.getBean("thriftServer");
			//调用登录服务
			LoginService.Client loginService = (LoginService.Client)springClient.getClient("LoginService");
			User user = loginService.login("penngo", "123");
			if (user != null) {
				System.out.println("登录成功:" + user.getId() + " "
						+ user.getName());
			} else {
				System.out.println("登录失败");
			}
			//调用注册服务
			RegisterService.Client registerClient = (RegisterService.Client)springClient.getClient("RegisterService");
			User user2 = registerClient.createUser("test", "123");
			if (user2 != null) {
				System.out.println("创建用户成功:" + user2.getId() + " "
						+ user2.getName());
			} else {
				System.out.println("创建用户失败");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


源码下载

© 著作权归作者所有

共有 人打赏支持
penngo
粉丝 76
博文 86
码字总数 55112
作品 2
广州
程序员
VigorYuan/spring-boot-thrift-server

#spring-boot-thrift-server 2016-05-09 更新 改变实现机制,项目启动后 使用spring ApplicationContextEvent 扫描带有 @EnableThriftServer 的注解 使用 TMultiplexedProcessor 以支持多接口...

VigorYuan ⋅ 2016/04/30 ⋅ 0

微服务架构实战学习(四):RPC 框架对比

下面是对市面上比较流行的 RPC 框架的对比 以上对比是我结合各框架的网上资料以及官方文档资源总结的,在实际的使用过程中。我们可以结合我们的业务场景来选择不同的框架。 虽然说没有最好的...

雨林_a1d6 ⋅ 06/11 ⋅ 0

Spring Cloud简介/版本选择/ZooKeeper例子搭建简单说明

一、什么是Spring Cloud 官方的说法就是Spring Cloud 给开发者提供一套按照一定套路快速开发分布式系统的工具。 具体点就是Spring Boot实现的微服务架构开发工具。它为微服务架构中涉及的配置...

easonjim ⋅ 2017/09/18 ⋅ 0

Spring集成Redis方案(spring-data-redis)(基于Jedis的单机模式)(待实践)

说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点。并且会与一些低版本的Spring有冲突,要看官方文档...

easonjim ⋅ 2017/10/05 ⋅ 0

分布式模块化 Java 开发平台--Castle-Platform

Castle-Platform是一个分布式、模块化的开发平台,目标是打造高性能、高扩展性的开发平台,完成通用的管理功能。采用了后台管理集中部署,会员业务系统可分离部署等特点,可独立区分后台管理...

tunsi ⋅ 2016/10/21 ⋅ 6

Spring Boot集成Spring Data Reids和Spring Session实现Session共享

首先,需要先集成Redis的支持,参考:http://www.cnblogs.com/EasonJim/p/7805665.html Spring Boot集成Spring Data Redis+Spring Session非常的简单,也不用担心版本问题,只需要引入相应的...

easonjim ⋅ 2017/11/10 ⋅ 0

Mybatis-Generator插件的使用与Spring集成Mybatis的配置

Mybatis-Generator插件 Mybatis-Generator是一个用于自动生成dao层接口、pojo以及mapper xml的一个Mybatis插件,该插件有三种用法:命令行运行、Eclipse插件、maven插件。个人觉得maven插件最...

ZeroOne01 ⋅ 04/15 ⋅ 0

Spring Framework体系结构简介

说明:以下转自Spring官方文档,用的版本为4.3.11版本。 一、引用官方文档 所述核心容器由以下部分组成, ,,,和(弹簧表达式语言)模块。 的和模块提供框架的基本零件,包括IOC和依赖注入...

easonjim ⋅ 2017/09/16 ⋅ 0

一文读懂 Spring Boot、微服务架构和大数据治理三者之间的故事

微服务架构 微服务的诞生并非偶然,它是在互联网高速发展,技术日新月异的变化以及传统架构无法适应快速变化等多重因素的推动下诞生的产物。互联网时代的产品通常有两类特点:需求变化快和用...

ityouknow ⋅ 05/16 ⋅ 0

对Mainstay配置的初步理解

通过Mainstay调用远程服务: 在集成Mainstay与Spring的jar包mainstay-spring-2.0.2-xdcstest.jar包中,提供了这么几个类: com.ximalaya.mainstay.spring.config.ClientConfig:用来配置Mai...

AlphaGo ⋅ 2016/03/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Greys Java在线问题诊断工具

Greys是一个JVM进程执行过程中的异常诊断工具。 在不中断程序执行的情况下轻松完成JVM相关问题排查工作 目标群体 有时候突然一个问题反馈上来,需要入参才能完成定位,但恰恰没有任何日志。回...

素雷 ⋅ 21分钟前 ⋅ 0

git从远程仓库拉取代码的常用指令

一种(比较麻烦的)拉代码的方法 git clone //克隆代码库,与远程代码库的主干建立连接,如果主干已经在就不用再clone啦,克隆路径为当前路径下的新创建的文件夹 git checkout -b //本地建立...

Helios51 ⋅ 35分钟前 ⋅ 0

005. 深入JVM学习—Java堆内存参数调整

1. JVM整体内存调整图解(调优关键) 实际上每一块子内存区域都会存在一部分可变伸缩区域,其基本流程:如果内存空间不足,则在可变的范围之内扩大内存空间,当一段时间之后,内存空间不紧张...

影狼 ⋅ 40分钟前 ⋅ 0

内存障碍: 软件黑客的硬件视图

此文为笔者近日有幸看到的一则关于计算机底层内存障碍的学术论文,并翻译(机译)而来[自认为翻译的还行],若读者想要英文原版的论文话,给我留言,我发给你。 内存障碍: 软件黑客的硬件视图...

Romane ⋅ 今天 ⋅ 0

SpringCloud 微服务 (七) 服务通信 Feign

壹 继续第(六)篇RestTemplate篇 做到现在,本机上已经有注册中心: eureka, 服务:client、order、product 继续在order中实现通信向product服务,使用Feign方式 下面记录学习和遇到的问题 贰 or...

___大侠 ⋅ 今天 ⋅ 0

gitee、github上issue标签方案

目录 [TOC] issue生命周期 st=>start: 开始e=>end: 结束op0=>operation: 新建issueop1=>operation: 评审issueop2=>operation: 任务负责人执行任务cond1=>condition: 是否通过?op3=>o......

lovewinner ⋅ 今天 ⋅ 0

浅谈mysql的索引设计原则以及常见索引的区别

索引定义:是一个单独的,存储在磁盘上的数据库结构,其包含着对数据表里所有记录的引用指针. 数据库索引的设计原则: 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索...

屌丝男神 ⋅ 今天 ⋅ 0

String,StringBuilder,StringBuffer三者的区别

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。 首先说运行速度,或者说是, 1.执行速度 在这方面运行速度快慢为:StringBuilder(线程不安全,可变) > StringBuffer...

时刻在奔跑 ⋅ 今天 ⋅ 0

java以太坊开发 - web3j使用钱包进行转账

首先载入钱包,然后利用账户凭证操作受控交易Transfer进行转账: Web3j web3 = Web3j.build(new HttpService()); // defaults to http://localhost:8545/Credentials credentials = Wallet......

以太坊教程 ⋅ 今天 ⋅ 0

Oracle全文检索配置与实践

Oracle全文检索配置与实践

微小宝 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部