Missian指南三:创建一个Missian服务器(使用spring)

在使用Missian时,spring是可选的,但是作者本人强烈推荐和Spring配合使用。Spring是一个伟大的项目,并且它不会对程序在运行时的效率带来任何损耗。

 

Missian在服务器端依赖与Mina,Missian只是提供一个Codec(协议编码解码,兼容TCP和HTTP)和一个Handler(调用Hessian序列化机制来反序列化数据、使用BeanLocator来定位这次调用的Bean)。熟悉Mina的朋友会很清楚Codec和Handler的概念;不熟悉的朋友也没关系,按照这个教程一样可以创建一个高效的服务来。对Mina没有兴趣的朋友可以直接跳到第七步:)

 

步骤一:创建一个spring配置文件。

Xml代码 复制代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  5. </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
</beans>

 

步骤二:配置文件中加入:

Xml代码 复制代码  收藏代码
  1. <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">  
  2.     <property name="customEditors">  
  3.         <map>  
  4.             <entry key="java.net.SocketAddress">  
  5.                 <bean class="org.apache.mina.integration.beans.InetSocketAddressEditor" />  
  6.             </entry>  
  7.         </map>  
  8.     </property>  
  9. </bean>  
	<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
		<property name="customEditors">
			<map>
				<entry key="java.net.SocketAddress">
					<bean class="org.apache.mina.integration.beans.InetSocketAddressEditor" />
				</entry>
			</map>
		</property>
	</bean>
 

这个是最后绑定端口时,用来将10.1.23.1:125转换成SocketAddress的,不用太关注。

 

步骤三:配置各个Mina的Filter

注意ExecutorFitler是使用的默认构造函数,要指定线程数,或者将已有的线程池传入,可以使用其它的构造函数;LoggingFilter中除了Exception之外的时间的Log级别已经全部设为DEBUG;CodecFilter是关键,这里引入了Missian的编码解码器。

Java代码 复制代码  收藏代码
  1. <bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" />   
  2. <bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">   
  3.     <constructor-arg>   
  4.         <bean class="com.missian.server.codec.MissianCodecFactory" />   
  5.     </constructor-arg>   
  6. </bean>   
  7. <bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter">   
  8.     <property name="messageReceivedLogLevel" value="DEBUG"/>   
  9.     <property name="messageSentLogLevel" value="DEBUG"/>   
  10.     <property name="sessionCreatedLogLevel" value="DEBUG"/>   
  11.     <property name="sessionClosedLogLevel" value="DEBUG"/>   
  12.     <property name="sessionIdleLogLevel" value="DEBUG"/>   
  13.     <property name="sessionOpenedLogLevel" value="DEBUG"/>   
  14. </bean>  
	<bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" />
	<bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
		<constructor-arg>
			<bean class="com.missian.server.codec.MissianCodecFactory" />
		</constructor-arg>
	</bean>
	<bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter">
		<property name="messageReceivedLogLevel" value="DEBUG"/>
		<property name="messageSentLogLevel" value="DEBUG"/>
		<property name="sessionCreatedLogLevel" value="DEBUG"/>
		<property name="sessionClosedLogLevel" value="DEBUG"/>
		<property name="sessionIdleLogLevel" value="DEBUG"/>
		<property name="sessionOpenedLogLevel" value="DEBUG"/>
	</bean>
 

 

步骤四:构建FilterChian

这里我把Codec放在线程池之前,因为编码解码是CPU密集型的操作,使用线程池并不能提高效率。当然了,有兴趣的朋友可以自己调整顺序做一下测试。

Java代码 复制代码  收藏代码
  1. <bean id="filterChainBuilder"  
  2.     class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">   
  3.     <property name="filters">   
  4.         <map>   
  5.             <entry key="codecFilter" value-ref="codecFilter" />   
  6.             <entry key="executor" value-ref="executorFilter" />   
  7.             <entry key="loggingFilter" value-ref="loggingFilter" />   
  8.         </map>   
  9.     </property>   
  10. </bean>  
	<bean id="filterChainBuilder"
		class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
		<property name="filters">
			<map>
				<entry key="codecFilter" value-ref="codecFilter" />
				<entry key="executor" value-ref="executorFilter" />
				<entry key="loggingFilter" value-ref="loggingFilter" />
			</map>
		</property>
	</bean>
 

 

步骤五:创建IoHandler。

这一步也很重要,引入了Missian的处理器,就是在这里调用了Hessian的序列化机制,并完成对相应的Bean的调用。

Xml代码 复制代码  收藏代码
  1. <bean id="minaHandler" class="com.missian.server.handler.MissianHandler">  
  2.     <constructor-arg>  
  3.         <bean class="com.missian.common.beanlocate.SpringLocator" />  
  4.     </constructor-arg>  
  5. </bean>  
	<bean id="minaHandler" class="com.missian.server.handler.MissianHandler">
		<constructor-arg>
			<bean class="com.missian.common.beanlocate.SpringLocator" />
		</constructor-arg>
	</bean>

MissianHandler接受一个BeanLocator的构造菜熟,注意这里直接给MissianHandler注入了一个SpringLocator,使得Missian有能力去Spring去寻找相应的Bean。

这里是一个很好的扩展点,有需要的话可以在BeanLocator上做做文章。

 

 

步骤六:创建一个Acceptor,监听端口

Java代码 复制代码  收藏代码
  1. <bean id="minaAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"  
  2.     init-method="bind" destroy-method="unbind">   
  3.     <property name="defaultLocalAddress" value=":1235" />   
  4.     <property name="handler" ref="minaHandler" />   
  5.     <property name="reuseAddress" value="true" />   
  6.     <property name="filterChainBuilder" ref="filterChainBuilder" />   
  7. </bean>  
	<bean id="minaAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
		init-method="bind" destroy-method="unbind">
		<property name="defaultLocalAddress" value=":1235" />
		<property name="handler" ref="minaHandler" />
		<property name="reuseAddress" value="true" />
		<property name="filterChainBuilder" ref="filterChainBuilder" />
	</bean>
 

到此位置,missian服务配置完毕。接下来配置一下业务逻辑的Bean。

 

步骤七:配置一个业务逻辑Bean,供Missian客户端调用

Java代码 复制代码  收藏代码
  1. <bean id="hello" class="com.missian.example.bean.HelloImpl"></bean>  
<bean id="hello" class="com.missian.example.bean.HelloImpl"></bean>

 上一篇指南里面创建的这个类第一次出境了,鼓掌……

注意bean的id叫做‘hello’,missian客户端就是通过‘hello’这个名称找到这个bean的,例如:http://www.abc.cn/hello。

值得一提的是如果客户端想通过http://www.abc.cn/p/hello来访问这个bean,那么这个bean的配置应该如此:

Java代码 复制代码  收藏代码
  1. <bean name="p/hello" class="com.missian.example.bean.HelloImpl"></bean>  
<bean name="p/hello" class="com.missian.example.bean.HelloImpl"></bean>

ID属性是不能出现斜杠的,所以通过name来定义这个bean。

 

 

步骤八:启动服务器

Java代码 复制代码  收藏代码
  1. public class ServerWithSpring {   
  2.     /**  
  3.      * @param args  
  4.      */  
  5.     public static void main(String[] args) {   
  6.         new ClassPathXmlApplicationContext("com/missian/example/server/withspring/applicationContext-*.xml");   
  7.     }   
  8. }  
public class ServerWithSpring {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new ClassPathXmlApplicationContext("com/missian/example/server/withspring/applicationContext-*.xml");
	}
}

 运行ServerWithSpring即启动了整个服务了。服务将监听1235端口,接受HTTP协议和TCP协议格式的请求。

 

 

步骤九:用Hessian来调用此服务

由于Missian服务器是兼容Hessian的,所以,在创建Missian客户端之前,让我们用Hessian客户端来测试一下这个服务吧。

Java代码 复制代码  收藏代码
  1. HessianProxyFactory factory = new HessianProxyFactory();   
  2.   
  3. Hello hello = (Hello) factory.create(Hello.class"http://localhost:1235/hello");   
  4. System.out.println(hello.hello("test"27));  
HessianProxyFactory factory = new HessianProxyFactory();

Hello hello = (Hello) factory.create(Hello.class, "http://localhost:1235/hello");
System.out.println(hello.hello("test", 27));

是的,你会发现调用成功了。

 

完整的配置文件如下

Java代码 复制代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">   
  5.   
  6.     <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">   
  7.         <property name="customEditors">   
  8.             <map>   
  9.                 <entry key="java.net.SocketAddress">   
  10.                     <bean class="org.apache.mina.integration.beans.InetSocketAddressEditor" />   
  11.                 </entry>   
  12.             </map>   
  13.         </property>   
  14.     </bean>   
  15.     <!-- The IoHandler implementation -->   
  16.     <bean id="minaHandler" class="com.missian.server.handler.MissianHandler">   
  17.         <constructor-arg>   
  18.             <bean class="com.missian.common.beanlocate.SpringLocator" />   
  19.         </constructor-arg>   
  20.     </bean>   
  21.   
  22.     <!-- the IoFilters -->   
  23.     <bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" />   
  24.     <bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">   
  25.         <constructor-arg>   
  26.             <bean class="com.missian.server.codec.MissianCodecFactory" />   
  27.         </constructor-arg>   
  28.     </bean>   
  29.     <bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter">   
  30.         <property name="messageReceivedLogLevel" value="DEBUG"/>   
  31.         <property name="messageSentLogLevel" value="DEBUG"/>   
  32.         <property name="sessionCreatedLogLevel" value="DEBUG"/>   
  33.         <property name="sessionClosedLogLevel" value="DEBUG"/>   
  34.         <property name="sessionIdleLogLevel" value="DEBUG"/>   
  35.         <property name="sessionOpenedLogLevel" value="DEBUG"/>   
  36.     </bean>   
  37.     <!-- The non-SSL filter chain. -->   
  38.     <bean id="filterChainBuilder"  
  39.         class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">   
  40.         <property name="filters">   
  41.             <map>   
  42.                 <entry key="codecFilter" value-ref="codecFilter" />   
  43.                 <entry key="executor" value-ref="executorFilter" />   
  44.                 <entry key="loggingFilter" value-ref="loggingFilter" />   
  45.             </map>   
  46.         </property>   
  47.     </bean>   
  48.     <!-- The IoAcceptor which binds to port 1235 server side -->   
  49.     <bean id="minaAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"  
  50.         init-method="bind" destroy-method="unbind">   
  51.         <property name="defaultLocalAddress" value=":1235" />   
  52.         <property name="handler" ref="minaHandler" />   
  53.         <property name="reuseAddress" value="true" />   
  54.         <property name="filterChainBuilder" ref="filterChainBuilder" />   
  55.     </bean>   
  56.   
  57.     <!-- your business bean, missian client will call this bean by 'hello' -->   
  58.     <bean id="hello" class="com.missian.example.bean.HelloImpl"></bean>   
  59.   
  60. </beans>  
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
		<property name="customEditors">
			<map>
				<entry key="java.net.SocketAddress">
					<bean class="org.apache.mina.integration.beans.InetSocketAddressEditor" />
				</entry>
			</map>
		</property>
	</bean>
	<!-- The IoHandler implementation -->
	<bean id="minaHandler" class="com.missian.server.handler.MissianHandler">
		<constructor-arg>
			<bean class="com.missian.common.beanlocate.SpringLocator" />
		</constructor-arg>
	</bean>

	<!-- the IoFilters -->
	<bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" />
	<bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter">
		<constructor-arg>
			<bean class="com.missian.server.codec.MissianCodecFactory" />
		</constructor-arg>
	</bean>
	<bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter">
		<property name="messageReceivedLogLevel" value="DEBUG"/>
		<property name="messageSentLogLevel" value="DEBUG"/>
		<property name="sessionCreatedLogLevel" value="DEBUG"/>
		<property name="sessionClosedLogLevel" value="DEBUG"/>
		<property name="sessionIdleLogLevel" value="DEBUG"/>
		<property name="sessionOpenedLogLevel" value="DEBUG"/>
	</bean>
	<!-- The non-SSL filter chain. -->
	<bean id="filterChainBuilder"
		class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
		<property name="filters">
			<map>
				<entry key="codecFilter" value-ref="codecFilter" />
				<entry key="executor" value-ref="executorFilter" />
				<entry key="loggingFilter" value-ref="loggingFilter" />
			</map>
		</property>
	</bean>
	<!-- The IoAcceptor which binds to port 1235 server side -->
	<bean id="minaAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
		init-method="bind" destroy-method="unbind">
		<property name="defaultLocalAddress" value=":1235" />
		<property name="handler" ref="minaHandler" />
		<property name="reuseAddress" value="true" />
		<property name="filterChainBuilder" ref="filterChainBuilder" />
	</bean>

	<!-- your business bean, missian client will call this bean by 'hello' -->
	<bean id="hello" class="com.missian.example.bean.HelloImpl"></bean>

</beans>
 

 Author: gh_aiyz

Forward : http://missian.iteye.com/blog/829864

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值