基于反射实现Thrift的服务注册和客户端调用的代理端,并结合前几节的HelloWorld接口、实现类以及连接池。
1.服务端代理
ThriftServerProxy.java
package cn.slimsmart.thrift.demo.proxy;
import java.lang.reflect.Constructor;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//服务端代理
public class ThriftServerProxy {
private final Logger logger = LoggerFactory.getLogger(getClass());
private int port;// 端口
private String serviceInterface;// 实现类接口
private Object serviceImplObject;// 实现类
@SuppressWarnings({ "unchecked", "rawtypes" })
public void start() {
new Thread() {
@Override
public void run() {
try {
TServerSocket serverTransport = new TServerSocket(getPort());
// 实现类处理类class
Class Processor = Class.forName(getServiceInterface() + "$Processor");
// 接口
Class Iface = Class.forName(getServiceInterface() + "$Iface");
// 接口构造方法类
Constructor con = Processor.getConstructor(Iface);
// 实现类处理类
TProcessor processor = (TProcessor) con.newInstance(serviceImplObject);
TBinaryProtocol.Factory protFactory = new TBinaryProtocol.Factory(true, true);
TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport);
args.protocolFactory(protFactory);
args.processor(processor);
TServer server = new TThreadPoolServer(args);
logger.info("Starting server on port " + getPort() + " ...");
System.out.println("Starting server on port " + getPort() + " ...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getServiceInterface() {
return serviceInterface;
}
public void setServiceInterface(String serviceInterface) {
this.serviceInterface = serviceInterface;
}
public Object getServiceImplObject() {
return serviceImplObject;
}
public void setServiceImplObject(Object serviceImplObject) {
this.serviceImplObject = serviceImplObject;
}
}
2.服务端spring配置
proxy/applicationContext-server.xml
<?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="true">
<description>thrift配置文件 </description>
<bean id="helloWorldImpl" class="cn.slimsmart.thrift.demo.helloworld.HelloWorldImpl" />
<!-- 服务端注册 -->
<bean id="helloWorld" class="cn.slimsmart.thrift.demo.proxy.ThriftServerProxy">
<property name="port" value="8080" />
<property name="serviceInterface" value="cn.slimsmart.thrift.demo.helloworld.HelloWorld" />
<property name="serviceImplObject" ref="helloWorldImpl" />
</bean>
</beans>
3.服务端启动类
ServerTest.java
package cn.slimsmart.thrift.demo.proxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.slimsmart.thrift.demo.proxy.ThriftServerProxy;
public class ServerTest {
@SuppressWarnings("resource")
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:proxy/applicationContext-server.xml");
ThriftServerProxy thriftServerProxy = (ThriftServerProxy) context.getBean(ThriftServerProxy.class);
thriftServerProxy.start();
}
}
4.客户端代理
ThriftClientProxy.java
package cn.slimsmart.thrift.demo.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TTransport;
import cn.slimsmart.thrift.demo.pool.ConnectionManager;
//客户端代理
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ThriftClientProxy {
private ConnectionManager connectionManager;
public ConnectionManager getConnectionManager() {
return connectionManager;
}
public void setConnectionManager(ConnectionManager connectionManager) {
this.connectionManager = connectionManager;
}
public Object getClient(Class clazz) {
Object result = null;
try {
TTransport transport = connectionManager.getSocket();
TProtocol protocol = new TBinaryProtocol(transport);
Class client = Class.forName(clazz.getName() + "$Client");
Constructor con = client.getConstructor(TProtocol.class);
result = con.newInstance(protocol);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
}
5.客户端spring配置
proxy/applicationContext-client.xml
<?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="true">
<description>thrift配置文件 </description>
<!-- 连接池配置 -->
<bean id="connectionProvider" class="cn.slimsmart.thrift.demo.pool.ConnectionProviderImpl">
<property name="serviceIP" value="127.0.0.1" />
<property name="servicePort" value="8080" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="10" />
<property name="testOnBorrow" value="true" />
<property name="testOnReturn" value="true" />
<property name="testWhileIdle" value="true" />
<property name="conTimeOut" value="2000" />
</bean>
<bean id="connectionManager" class="cn.slimsmart.thrift.demo.pool.ConnectionManager">
<property name="connectionProvider" ref="connectionProvider"/>
</bean>
<bean id="thriftClientProxy" class="cn.slimsmart.thrift.demo.proxy.ThriftClientProxy">
<property name="connectionManager" ref="connectionManager"/>
</bean>
</beans>
6.客户端启动类
ClientTest.java
package cn.slimsmart.thrift.demo.proxy;
import org.apache.thrift.TException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.slimsmart.thrift.demo.helloworld.HelloWorld;
import cn.slimsmart.thrift.demo.proxy.ThriftClientProxy;
public class ClientTest {
@SuppressWarnings("resource")
public static void main(String[] args) throws TException {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:proxy/applicationContext-client.xml");
ThriftClientProxy thriftClientProxy = (ThriftClientProxy) context.getBean(ThriftClientProxy.class);
HelloWorld.Iface client = (HelloWorld.Iface)thriftClientProxy.getClient(HelloWorld.class);
System.out.println(client.sayHello("Jack"));
}
}