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

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

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

  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>

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

  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>

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

步骤三:配置各个Mina的Filter

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

  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>

步骤四:构建FilterChian

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

  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>

步骤五:创建IoHandler。

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

  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>

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

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

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

  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>

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

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

  1. <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的配置应该如此:

  1. <bean name="p/hello" class="com.missian.example.bean.HelloImpl"></bean>

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

步骤八:启动服务器

  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. }

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

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

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

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

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

完整的配置文件如下

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

Missian指南三:创建一个Missian服务器(使用spring)的更多相关文章

  1. 【重点突破】——使用Express创建一个web服务器

    一.引言 在自学node.js的过程中有一个非常重要的框架,那就是Express.它是一个基于NodeJs http模块而编写的高层模块,弥补http模块的繁琐和不方便,能够快速开发http服务器.这 ...

  2. 十七、创建一个 WEB 服务器(一)

    1.Node.js 创建的第一个应用 var http=require("http") http.createServer(function (req,res) { res.wri ...

  3. nodejs创建一个HTTP服务器 简单入门级

    const http = require('http');//请求http.createServer(function(request, response){    /*createServer该函数 ...

  4. 用NodeJS创建一个聊天服务器

    Node 是专注于创建网络应用的,网络应用就需要许多I/O(输入/输出)操作.让我们用Node实现有多么简单,并且还能轻松扩展. 创建一个TCP服务器 var net = require('net') ...

  5. Delphi for iOS开发指南(3):创建一个FireMonkey iOS应用程序

    http://cache.baiducontent.com/c?m=9d78d513d9d431a94f9d92697d60c015134381132ba1d0020fa48449e3732b4b50 ...

  6. [AirFlow]AirFlow使用指南三 第一个DAG示例

    经过前两篇文章的简单介绍之后,我们安装了自己的AirFlow以及简单了解了DAG的定义文件.现在我们要实现自己的一个DAG. 1. 启动Web服务器 使用如下命令启用: airflow webserv ...

  7. [git 学习篇]自己在github创建一个远程服务器创库

    现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举 ...

  8. 用 eclipse 创建一个简单的 meaven spring springMvc mybatis 项目

    下面是整体步骤: 1: 先创建一个Maven 项目: 选择跳过骨架: 因为要搭建的是 web 项目  所以这个地方选择 war 包; 点击完成 这样就完成 Maven项目的搭建: 接下俩 先把 Mav ...

  9. python web编程 创建一个web服务器

    这里就介绍几个底层的用于创建web服务器的模块,其中最为主要的就是BaseHTTPServer,很多框架和web服务器就是在他们的基础上创建的 基础知识 要建立一个Web 服务,一个基本的服务器和一个 ...

随机推荐

  1. Android 中文 API (101) —— AsyncTask

    一.结构 public abstract class AsyncTask extends Object java.lang.Object android.os.AsyncTask<Params, ...

  2. WPF OnApplyTemplate 不执行 或者执行滞后的疑惑

    OnApplyTemplate 不执行 平时如何开发自定义控件的 在WPF自定义控件开发的过程中遇到了这样一个问题,属性更改事件在OnApplyTemplate之前执行.我在写自定义控件的时候,喜欢通 ...

  3. Java并发编程的艺术,解读并发编程的优缺点

    并发编程的优缺点 使用并发的原因 多核的CPU的背景下,催生了并发编程的趋势,通过并发编程的形式可以将多核CPU的计算能力发挥到极致,性能得到提升. 在特殊的业务场景下先天的就适合于并发编程. 比如在 ...

  4. kafka基础一

    基本概念: 消息系统的组成由生产者,消费者以及存储系统.消费者从存储系统中读取生产者生产的消息.Kafka作为分布式的消息系统支持多个生产者多个消费者,写消息时允许多个生产者写到同一个Partitio ...

  5. git 如何生成 SSH 公钥

    1.打开你的git bash 窗口 2.进入.ssh目录:cd ~/.ssh 3.找到id_rsa.pub文件:ls 4.查看公钥:cat id_rsa.pub    或者vim id_rsa.pub ...

  6. Android 桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    首先是一个小的悬浮窗显示的是当前使用了百分之多少的内存,点击一下小悬浮窗,就会弹出一个大的悬浮窗,可以一键加速.好,我们现在就来模拟实现一下类似的效果. 先谈一下基本的实现原理,这种桌面悬浮窗的效果很 ...

  7. Spring 的AOP

    AOP:面向切面编程,相对于OOP面向对象的编程 Spring的AOP的存在的目的是为了解耦.AOP可以让一组类共享相同的行为.在OOP中只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为 ...

  8. MvvmCross框架在XamarinForms中的使用入门

    做XamarinForms快一年了,最近趁着项目不是很紧,有点空闲的时间,研究了一下MvvmCross这个框架,感觉挺高大上的.一边研究一下写点入门的东西吧,大部分的东西github都有. 1添加Pa ...

  9. 【转】如何在Git中撤销一切

    翻译:李伟 审校:张帆译自:Github 任何一个版本控制系统中,最有用的特性之一莫过于 “撤销(undo)”操作.在Git中,“撤销”有很多种含义. 当你完成了一次新的提交(commit),Git会 ...

  10. Android商城开发系列(十)—— 首页活动广告布局实现

    在上一篇博客当中,我们讲了频道布局的实现,接下来我们讲解一下活动广告布局的实现,效果如下图: 这个是用viewpager去实现的,新建一个act_item.xml,代码如下所示: <?xml v ...