使用spring mvc或者resteasy构建restful服务
看到最近一个项目里用resteasy来构建restful接口,有点不明白,不少Spring mvc4.0以后也可以很方面的实现restful服务吗,为啥还要在Spring MVC的项目里还引入resteasy?估计还是开发人员根据自己技术能力自由选择的吧,毕竟resteasy引入也很简单。为了解惑,了解了一下resteasy。
resteasy 是 jboss的一个开源restful service实现参考。本文假设读者熟悉spring mvc,但是不了解或者没有使用过resteasy的用户。
其实一直以来,笔者实际都是使用spring mvc,对于研究resteasy没有兴趣。至于最近研究resteasy,纯属因为现在公司使用dubbox作为rpc框架,而dubbox使用resteasy作为REST实现库。
简单地说,resteasy核心就是一个servlet前端控制器,理念都一样。
应该来说,resteasy的优势在于相比spring mvc而言,更加的专注,简单。就大型应用而言,绝对是spring mvc占据优势。
就简洁性而言,应该来说在spring 4.0引入spring restcontroller之后,优势就没有那么明显了,应该来说3.2之前对restful还不那么有信心。
就像我们现在发现基本上mvc上spring mvc占据了绝大部分的新项目,估计以后resteasy也会小众化。
至于说resteasy为什么活下来,感觉上spring社区有个比较明显的倾向就是好像不怎么吃螃蟹,等到趋势比较明朗之后,要么就整合对方,要么就强行自己引入一套接口玩死对方。
resteasy是JAX-RS的参考实现之一,规范制定者是核心人员之一,所以概念和属于上基本上完全各种restful service教材上能够直接对应。spring mvc方面,就没有那么直接的对应了,估计是鄙视J2EE的一种商业手法。
就应用而言,如果restful作为rpc的实现机制,resteasy应该是有优势的,毕竟集成没有spring mvc那么多配置(当然spring cloud除外),但作为应用,估计干不过spring mvc。
resteasy的实现原理也与Spring MVC 的rest有相似的地方,可能后者也是借鉴前者的吧
先在web.xml文件中做了以下配置:
其中ResteasyBootstrap作为监听器是拉起Resteasy服务的入口,在服务启动时主要做了以下动作:
1)通过ListenerBootstrap组件读取在web.xml文件中的一些系统配置信息,创建ResteasyDeployment对象,并将这些配置信息初始化到该对象中,其中就包括将”resteasy.resources”中配置的资源类的路径初始化到其成员变量resourceClasses中;
2)通过调用ResteasyDeployment的start()方法,并根据相关配置信息初始化Resteasy的核心组件ResteasyProviderFactory ,Dispatcher,Registry.
3)最关键的部分是调用registration(),在该方法中会遍历之前在web.xml中配置的资源并将其注册到Registry中, 以Demo中的例子来看会遍历resourceClasses中配置好的TestRest资源路径,并加载该类然后通过调用registry.addPerRequestResource(clazz)注册到Registry中; 详见以下代码片段:
在addPerRequestResource()中做了两个主要的事情:其中一个是会使用相应的ResourceFactory来包装资源类TestRest,见以下代码片段:
通过阅读POJOResourceFactory的源码可以了解到其作用就是包含了资源类的所有元信息,因此它可以利用ResteasyProviderFactory提供的注入器在需要时通过createResource()来创建资源类TestRest的对象;
第二个主要的事情是Registry可以通过资源类中的元信息来解析上面的JAX-RS注解,并将该注解的路径和对应的方法生成的invoker对象注册到Registry中,在Demo中就是把”/path1/subpath/{id}”和 test()方法的invoker对象注册到Registry中。
(Resteasy在服务启动时初始化过程图)
在web.xml文件中另一个配置是配置了HttpServletDispatcher,该类是HttpServlet的实现是所有请求的入口,通过其service()方法最终将请求交给之前启动服务时已经初始化好的Dispatcher对象来处理. 以Demo为例,当请求”http://localhost:8080/resteasydemo/path1/subpath/123”过来时,Dispatcher对象会调用其成员变量Registry对象来解析该请求中的路径”/path1/subpath/123”, 然后匹配到相应的invoker来执行客户端请求(详见以下代码段),并将结果返回,页面会显示”Hello 123”;
(Resteasy 客户端请求处理流程图)
四、总结
通过对Resteasy源码的解读分析我们就可以解答刚开始的三个问题:
1)谁来接受来自客户端的请求,并进行分发交给对应的对象的方法去处理。
----->HttpServletDispatcher,(接受并分发客户端http请求)
2)负责处理客户端请求的对象由谁来负责产生。
----->ResourceFactory (在服务器启动时通过web.xml读取class的配置信息然后通过反射机制产生)
3)如何解析Java类上面的注解,使客户端过来的请求可以找到对应的方法去执行。
------>Registry(服务器启动时加载用户自定义Rest资源时,会解析上面的注解,并将注解相对路径和该类中执行的方法建立对应关系注册到Registry中,当客户端请求过来时会根据请求中的相对路径去Registry中查找对应的invoker对象,然后执行并将处理结果返回)
Resteasy就是通过以上几个核心组件的相互配合,最终将一个JavaBean发布成Rest服务,这种基于服务注册的实现方式,使得Resteasy具有较好的可扩展性,例如它能很好的和Spring进行整合将SpringBean发布成Rest服务,它是如何做到的呢?首先扩展了Resteasy的ResourceFactory实现了一个SpringResourceFactory(用来从Spring容器中获得对象),然后在服务启动时当Spring容器初始化好以后,通过扩展Spring的BeanFactoryPostProcessor,将Spring容器中初始化好的SpringBean以及对应的SpringResourceFactory注册到Resteasy的Registry中.这样客户端请求过来后,当请求路径在Registry中匹配到相应的SpringBean时就可以调用该SpringBean的ResourceFactory的createResource方法,该方法可以从Spring容器中获得对象来处理请求。
Resteasy发布Rest服务的两种方式:
一种是通过listener (ResteasyBootstrap)方式在server启动时通过该listener的contextInitialized()初始化Resteasy核心组件及Rest资源。
第二种是如果没有在web.xml中配置ResteasyBootstrap监听器,则在HttpServletDispatcher,第一次请求过来时通过servlet的init方法初始化Resteasy核心组件及Rest资源。
无论哪种方式原理都是一样的,只是初始化的时机不同。http://blog.csdn.net/skydivingwang/article/details/77961872
使用spring mvc或者resteasy构建restful服务的更多相关文章
- 关于使用spring mvc或者resteasy构建restful服务的差别与比较
resteasy 是 jboss的一个开源java api for restful service(JSR 311,sun 2008年发布,最新GA版本是2.0, JAX-RS 2.0 (JSR-33 ...
- 使用 Spring 3 MVC HttpMessageConverter 功能构建 RESTful web 服务
原文地址:http://www.ibm.com/developerworks/cn/web/wa-restful/ 简介: Spring,构建 Java™ 平台和 Enterprise Edition ...
- Springboot & Mybatis 构建restful 服务五
Springboot & Mybatis 构建restful 服务五 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务四 2 restful ...
- Springboot & Mybatis 构建restful 服务二
Springboot & Mybatis 构建restful 服务二 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务一 2 restful ...
- Springboot & Mybatis 构建restful 服务
Springboot & Mybatis 构建restful 服务一 1 前置条件 jdk测试:java -version maven测试:命令行之行mvn -v eclipse及maven插 ...
- 手把手教你用Spring Cloud和Docker构建微服务
什么是Spring Cloud? Spring Cloud 是Pivotal提供的用于简化分布式系统构建的工具集.Spring Cloud引入了云平台连接器(Cloud Connector)和服务连接 ...
- Spring boot学习1 构建微服务:Spring boot 入门篇
Spring boot学习1 构建微服务:Spring boot 入门篇 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...
- 使用 Spring Cloud 和 Docker 构建微服务架构
如何使用Spring Boot.Spring Cloud.Docker和Netflix的一些开源工具来构建一个微服务架构. 本文通过使用Spring Boot.Spring Cloud和Docker构 ...
- 用Jersey构建RESTful服务7--Jersey+SQLServer+Hibernate4.3+Spring3.2
一.整体说明 本例执行演示了用 Jersey 构建 RESTful 服务中.怎样集成 Spring3 二.环境 1.上文的项目RestDemo 2.Spring及其它相关的jar ,导入项目 三.配置 ...
随机推荐
- Laravel5.1 学习笔记1, 目录结构和命名空间(待修)
自从用 Laravel4做了个小网站,使用了数据库ORM Eloquent, 就放下了一段时间,想不到这个与Asp.net MVC 有着异曲同工之妙的框架已经出了下个版本,而且还有不小的改动,因此不得 ...
- Centos7.5 在桌面创建AndroidStudio快捷方式
Centos7 在桌面创建AndroidStudio快捷方式 前言 最近安装了Centos7,打算将开发平台转移到Linux下,安装好AndroidStudio后,桌面没有快捷方式有些不习惯,随自己创 ...
- Deutsch lernen (08)
1. empfehlen - empfahl - hat empfohlen 推荐:劝说,劝告 Können Sie mir einen guten Artz empfehlen? jemand e ...
- ASP.net获取当前url各种属性(文件名、参数、域名等)的方法
假设当前页完整地址是:http://www.test.com/aaa/bbb.aspx?id=5&name=kelli "http://"是协议名 "www.te ...
- **ML : ML中的最优化方法
前言: 在机器学习方法中,若模型理解为决策模型,有些模型可以使用解析方法.不过更一般的对模型的求解使用优化的方法,更多的数据可以得到更多的精度. AI中基于归纳的方法延 ...
- c#如何用代码开启cmd指定命令(如:运行一个手机adb shell命令)
else if (this.Mode == TravelMode.AutoRecodeMode) { DateTime StartDate = DateTime.Now; string args = ...
- [Intermediate Algorithm] - Arguments Optional
题目 创建一个计算两个参数之和的 function.如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果. 例如,add(2, 3) 应该返回 5,而 ...
- Memcached 之分布式算法原理
memcached并不像mongodb一样可以配置多个节点,并且节点之间可以”自动分配数据“,即相互通信,所以我们在做memcache分布式集群的时候要有一个算法来保证当一台memcache服务器宕机 ...
- Linux 重要文件目录
文件系统层次化标准(Filesystem Hierarchy Standard)[FHS] 树形结构 /boot 开机所需文件——内核开机菜单以及所需的配置文件等 /dev 以文件形式存放任何设备与接 ...
- html 报告页面样式
修改了下HTML页面样式 页面代码 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...