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