spring与thrift集成

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

源码下载

时间: 2024-08-15 07:30:02

spring与thrift集成的相关文章

细说shiro之五:在spring框架中集成shiro

官网:https://shiro.apache.org/ 1. 下载在Maven项目中的依赖配置如下: <!-- shiro配置 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${version.shiro}</version> </dependency&g

菜鸟调错(四)——Spring与DWR集成,配置文件报错

背景简介: 该项目是市信用办的一个系统,之前好像是一个石家庄的公司负责的.我属于是半路接手.拿到源码后,根据他们给的简(shao)单(de)明(ke)了(lian)的说明把项目搭起来.结果可想而知,项目文件一片红.于是就开始解决这些错误,好在很多错误都是类似的.经过一番捣鼓,大部分的错误都解决了,有一个Spring跟DWR集成配置的错误,错误信息如下: Multiple annotations found at this line: - schema_reference.4: Failed to

spring与ibatis集成之事务部分源码解析

ibatis是一个非常优秀的半自动ORM框架,相较于许多人认为编写sql和配置字段映射会降低开发效率,我认为在数据库最易成为系统瓶颈的情况下,开发人员必须通过手动编写sql来保证sql执行的高效,并在编写过程中思考表结构的设计是否合理.网上已有许多关于ibatis架构和映射实现原理解析的文章,本文主要讨论ibatis和spring集成后事务管理的实现.在spring和ibatis集成后,有两种方式执行sql:第一种是dao继承spring的SqlMapClientDaoSupport,具体的sq

spring 和 mybatis集成的warn问题

warn:Skipping MapperFactoryBean with name 'appOperateRecordMapper' and 'XX.XX.XX.daor' mapperInterface. Bean already defined with the same name! 2014-07-22 18:02:29  WARN [main] (ClassPathMapperScanner.java:155) - No MyBatis mapper was found in '[XX.

Spring与Struts2集成开发

Struts2和Spring都是不错的开源框架,Spring与Struts2集成开发,把二者结合在一起使用,开发效果更佳,效率杠杠的.下面介绍一下如何将Spring与Struts2集成在一起开发.分七步战略: 1.添加Struts2 支持jar包 :注意:加上一个Struts-spring-plugin(集成)插件包 2.添加spring 支持jar包 3.编写struts.xml配置文件 注意:Action是交由Spring管理:所以action class属性应和spring 中配置的Act

java web项目(spring项目)中集成webservice ,实现对外开放接口

什么是WebService?webService小示例 点此了解 下面进入正题: Javaweb项目(spring项目)中集成webservice ,实现对外开放接口步骤: 准备: 采用与spring兼容性较好的cxf来实现 cxf 的  jar下载地址: http://cxf.apache.org/download.html 选择zip格式下载,解压后的lib目录下的jar 需要最少的jar如下: cxf-2.3.3.jargeronimo-annotation_1.0_spec-1.1.1.

在spring环境下集成ActiveMQ

1.参考文献 Spring集成ActiveMQ配置 Spring JMS异步发收消息 ActiveMQ 2.环境 在前面的一篇ActiveMQ入门实例中我们实现了消息的异步传送,这篇博文将如何在spring环境下集成ActiveMQ.如果要在spring下集成ActiveMQ,那么就需要将如下jar包导入项目: 本文有两篇参考文献,因此有两个实例,项目结构如下图所示: 3.实例1 信息发送者:HelloSender.java package edu.sjtu.erplab.springactiv

spring springMVC mybatis 集成

最近闲来无事,整理了一下spring springMVC mybatis 集成,关于这个话题在园子里已经有很多人写过了,我主要是想提供一个完整的demo,涵盖crud,事物控制等. 整个demo分三个层次: 一.简单模式:整个框架的参数传递不使用实体对象,统一用Map来存储变量,对mybatis部分不使用mapper接口,使用SqlSessionDaoSupport 提供的SqlSession 来操作mapper XML文件中的命令.这种方式的好处是框架层次结构很简单,适合快速开发,缺点是没有实

Spring Boot Admin 集成自定义监控告警

Spring Boot Admin 集成自定义监控告警 前言 Spring Boot Admin 是一个社区项目,可以用来监控和管理 Spring Boot 应用并且提供 UI,详细可以参考 官方文档. Spring Boot Admin 本身提供监控告警功能,但是默认只提供了 Hipchat.Slack 等国外流行的通讯软件的集成,虽然也有邮件通知,不过考虑到使用体检决定二次开发增加 钉钉 通知. 本文基于 Spring Boot Admin 目前最新版 1.5.7. 准备工作 Spring