spring與thrift集成,能夠使服務調用和發佈更方便。php
本文代碼是在上篇基礎上改進,部分代碼介紹請參考上一篇Thrift的java和php數據交互(http://my.oschina.net/penngo/blog/489311)java
服務器端spring配置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>
服務發佈實現apache
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>
客戶端調用例子this
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(); } } }
源碼下載spa