Apache Thrift 初学小讲(六)【spring】

这节把spring整合进Thrift,这次用maven来构建工程,maven的pom.xml加上依赖:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.3.7.RELEASE</version>
</dependency>

<dependency>
	<groupId>org.apache.thrift</groupId>
	<artifactId>libthrift</artifactId>
	<version>0.9.3</version>
</dependency>

1 客户端:我们可以把transport,protocol以及根据接口定义文件生成的ThriftTest.Client的实例化放到spring容器中,由spring容器维护它们的依赖关系,这样客户端的调用代码会简洁很多,并且ThriftTest.Client的transport和protocol将是可配置的。

spring-config-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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context.xsd">
	
    <!-- <context:component-scan base-package="thrift.test"/> -->
    
    <bean id="tSocket" class="org.apache.thrift.transport.TSocket" scope="prototype">
	    <constructor-arg name="host" value="localhost"/>
	    <constructor-arg name="port" value="9090"/>
	    <property name="timeout" value="1000"/>
	</bean>
	
	<bean id="tFastFramedTransport" class="org.apache.thrift.transport.TFastFramedTransport" init-method="open" destroy-method="close" scope="prototype">
	    <constructor-arg name="underlying" ref="tSocket"/>
	</bean>
	
	<bean id="tCompactProtocol" class="org.apache.thrift.protocol.TCompactProtocol" scope="prototype">
	    <constructor-arg name="transport" ref="tFastFramedTransport"/>
	</bean>
	
	<bean id="testClient" class="thrift.test.ThriftTest.Client" scope="prototype">
	    <constructor-arg name="prot" ref="tCompactProtocol"/>
	</bean>

</beans>

TestClient.java:

package com.halloffame.thriftspring;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import thrift.test.ThriftTest;
import thrift.test.User;

public class TestClient {
	public static final AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-config-client.xml");
	
    public static void main(String [] args) throws Exception {
	    ThriftTest.Client testClient = (ThriftTest.Client)context.getBean("testClient");
	    
        //getUser就是ThriftTest.thrift所定义的接口
        User user = testClient.getUser(2); 
        System.out.println("名字:"+ user.getName());
        
        //context.registerShutdownHook();
        //context.close();
        testClient.getInputProtocol().getTransport().close();
    }
}

2 服务端:本来也想把那些transport,protocol之类的放到spring当中,但是发现一些成员变量是没有set方法的,无法依赖注入。不过服务端最重要的还是业务逻辑的实现类TestHandler,把这个放到spring容器里。服务端采用注解配置类SpringConfigServer。

SpringConfigServer.java:

package com.halloffame.thriftspring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration //表明这是注解配置类,相当于spring-config-client.xml
@ComponentScan //相当于xml配置文件里的标签<context:component-scan .../>
public class SpringConfigServer {

}

TestHandler.java:

package com.halloffame.thriftspring;

import org.apache.thrift.TException;
import org.springframework.stereotype.Component;

import thrift.test.ThriftTest;
import thrift.test.User;

/**
 * 具体的业务逻辑类
 * 实现ThriftTest.thrift里的getUser接口
 */
@Component //由spring容器实例化管理等
public class TestHandler implements ThriftTest.Iface {

	@Override
	public User getUser(int id) throws TException {
		System.out.println("id==>" + id); 
		if (id == 2 ) {
			User user = new User();
			user.setId(2);
			user.setName("另外一个烟火");
			return user;
		}
		return null;
	}

}

TestServer.java:

package com.halloffame.thriftspring;

import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.TFastFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import thrift.test.ThriftTest;

public class TestServer {
	public static final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfigServer.class);
	
	public static void main(String [] args) throws Exception {
		//从spring容器中取得业务处理bean TestHandler
		ThriftTest.Iface iface = context.getBean(TestHandler.class);
		 
        //ThriftTest.Processor是生成的服务端代码
        ThriftTest.Processor testProcessor = new ThriftTest.Processor(iface);	
        //指定的通信协议
        TProtocolFactory tProtocolFactory = new TCompactProtocol.Factory(); 
        //指定的通信方式
        TTransportFactory tTransportFactory = new TFastFramedTransport.Factory(); 

        int port = 9090;
    	TNonblockingServerSocket tNonblockingServerSocket =
    			new TNonblockingServerSocket(new TNonblockingServerSocket.NonblockingAbstractServerSocketArgs().port(port));
    	TThreadedSelectorServer.Args tThreadedSelectorServerArgs
          	= new TThreadedSelectorServer.Args(tNonblockingServerSocket);
    	tThreadedSelectorServerArgs.processor(testProcessor);
    	tThreadedSelectorServerArgs.protocolFactory(tProtocolFactory);
    	tThreadedSelectorServerArgs.transportFactory(tTransportFactory);
    	//指定的服务器模式
    	TServer serverEngine = new TThreadedSelectorServer(tThreadedSelectorServerArgs);
        System.out.println("Starting the server on port " + port + "...");
        serverEngine.serve();
	}
}

3 工程结构图:


 

依次运行TestServer,TestClient,结果如预期。

附件是整个eclipse的maven工程。

猜你喜欢

转载自zhuwx.iteye.com/blog/2371657
今日推荐