随着异步 I/O 和 Netty 等框架的流行,响应式编程逐渐走入大众的视野。但是,响应式编程本身并不是太新的概念,这个术语最早出现在 1985 年 David Harel 和 Amir Pnueli 的论文“响应式系统的开发”之中,他们对复杂计算机系统的特征进行了归纳,提出了一种新颖的二分方式:转换式(Transformative)与响应式(Reactive)系统。转换式系统接收已知的一组输入,转换这些输入并产生输出,而响应式系统则会持续受到外部环境的刺激,它们的角色就是持续响应刺激。在构建响应式 Web 服务上,Spring 5 中引入了全新的编程框架,那就是 Spring WebFlux。作为一款新型的 Web 服务开发框架,它与传统的 WebMVC 相比具体有哪些优势呢?
介绍
Spring WebFlux 作为一个响应式 (reactive-stack) web 框架补充,在 5.0 的版本开始加入到 Spring 全家桶。这是一个完全非阻塞的,支持 Reactive Streams, 运行在诸如 Netty, Undertow, 以及 Servlet 3.1+ 容器上的,Spring WebFlux 构建在 Reactor 框架之上,提供了基于注解和函数式两种方式来配置和运行。Spring WebFlux 可以让你使用更少的线程去处理并发请求,同时能够让你使用更少的硬件资源来拓展你的应用。WebFlux 使用Netty作为默认的web服务器,其依赖于非阻塞IO,并且每次写入都不需要额外的线程进行支持。也可以使用Tomcat、Jetty容器,不同与SpringMVC依赖于Servlet阻塞IO,并允许应用程序在需要时直接使用Servlet API,WebFlux依赖于Servlet 3.1非阻塞IO。使用Undertow作为服务器时,WebFlux直接使用Undertow API而不使用Servlet API。
特点
场景
WebFlux 用于构建响应式 Web 服务。微服务架构的兴起为 WebFlux 的应用提供了一个很好的场景。我们知道在一个微服务系统中,存在数十乃至数百个独立的微服务,它们相互通信以完成复杂的业务流程。这个过程势必会涉及大量的 I/O 操作,尤其是阻塞式 I/O 操作会整体增加系统的延迟并降低吞吐量。如果能够在复杂的流程中集成非阻塞、异步通信机制,我们就可以高效处理跨服务之间的网络请求。针对这种场景,WebFlux 是一种非常有效的解决方案。控制层一旦使用 Spring WebFlux,它下面的安全认证层、数据访问层都必须使用 Reactive API。其次,Spring Data Reactive Repositories 目前只支持 MongoDB、Redis 和 Couchbase 等几种不支持事务管理的 NOSQL。技术选型时一定要权衡这些弊端和风险。
响应式编程
响应式编程是一种面向数据流和变化传播的编程范式,这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播,电子表格程序就是响应式编程的。
响应式应用应该具备如下的四个特点:
并发模型
WebFlux模型主要依赖响应式编程库Reactor,Reactor 有两种模型,Flux 和 Mono,提供了非阻塞、支持回压机制的异步流处理能力。WebFlux API接收普通Publisher作为输入,在内部使其适配Reactor类型,使用它并返回Flux或Mono作为输出。
介绍
SpringMvc是一种基于java的实现Mvc设计模式的请求驱动类型的轻量级web框架,属于SpringFrameWork的后续产品,已经融合在Spring Web Flow中,SpringMvc已经成为目前最主流的MVC框架之一,并且随着Spring3.0的发布,全面超越Struts2,成为最优秀的mvc框架,他通过一套注解,让一个简单的java类成为处理请求的控制器,他无需实现任何接口,同时他还支持RESTful编程风格的请求。
特点
MVC
Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。
并发模型
servlet由servlet container进行生命周期管理。container启动时构造servlet对象并调用servlet init()进行初始化;container关闭时调用servlet destory()销毁servlet;container运行时接受请求,并为每个请求分配一个线程(一般从线程池中获取空闲线程)然后调用service()。
处理请求的时候同步操作,一个请求对应一个线程来处理,并发上升,线程数量就会上涨(上线文切换,内存消耗大)影响请求的处理时间。现代系统多数都是IO密集的,同步处理让线程大部分时间都浪费在了IO等待上面。虽然Servlet3.0后提供了异步请求处理与非阻塞IO支持,但是使用它会远离Servlet API的其余部分,比如其规范是同步的(Filter, Servlet)或阻塞的(getParameter,getPart),而且其对响应的写入仍然是阻塞的。
Spring WebFlux 不是 Spring MVC 的替代方案,Spring WebFlux 是 Spring Framework 5.0中引入的新的响应式web框架。与Spring MVC不同,它不需要Servlet API,是完全异步且非阻塞的,并且通过Reactor项目实现了Reactive Streams规范。Spring MVC依然构建在 Servlet API 以及 Servlet 容器之上;Spring Security 为两种不同的技术栈提供了安全性的支持,Spring Data 分别为两种不同的技术栈实现了 Repository;在数据访问方面,响应式 Repository 已经涵盖了 Mongo、Cassandra、Redis 以及 Couchbase。但是在关系型数据库方面,因为 JBDC 规范本身就是阻塞式的,所以进展并不明显。但是,像 PostgreSQL 和 MySQL 已经有了异步驱动。异步非阻塞并不会使程序运行得更快。WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性。Spring WebFlux 是一个异步非阻塞的 Web 框架,所以,它特别适合应用在 IO 密集型的服务中,比如微服务网关这样的应用中。
pring MVC的表单标签为Java程序员提供了许多额外的支持。例如数据绑定,允许自动设置数据并从Java对象中检索数据。
从2.0版本开始,Spring提供了一组全面的数据绑定感知标记,用于在使用JSP和Spring Web MVC时处理表单元素。每个标记都支持其相应HTML标记对应的属性集,使标记熟悉且直观易用。标记生成的HTML符合HTML 4.01 / XHTML 1.0 标准。
在本文中我们会浏览所有这些表单标签,并查看每个标签的使用方式。
表单标记库被捆绑在spring-webmvc.jar中,库描述符称为spring-form.tld。
要使用此库中的标记,请将以下指令添加到JSP页面的顶部:
此标记呈现HTML“form”标记,并公开内部标记的绑定路径以进行绑定。 它将命令对象放在PageContext中,以便内部标记可以访问命令对象。 此库中的所有其他标记都是表单标记的嵌套标记。
假设我们有一个名为User的域对象。它是一个JavaBean,具有firstName和lastName等属性。我们将它用作表单控制器的表单支持对象,它返回form.jsp。如下所示:
firstName和lastName值是从页面控制器放置在PageContext中的命令对象中检索的。加载表单时,Spring MVC将对user.getFirstName()和getLastName()(getter方法)进行分类。提交表单时,Spring MVC将调用user.setFirstName()和user.setLastName()方法。 生成的HTML看起来是这样:
input 标记默认使用绑定值和type='text'呈现HTML 'input'标记,举个例子:
生成的HTML代码如下所示:
此标记呈现带有“checkbox”类型的HTML “input”标记,例如:
生成的代码如下所示:
此标记呈现多个带有“checkbox”类型的HTML “input”标记,示例如下:
此标记呈现带有“radio”类型的HTML “input”标记,典型的使用模式将涉及绑定到同一属性但具有不同值的多个标记实例:
此标记呈现多个带有“radio”类型的HTML “input”标记,例如:
此标记使用绑定值呈现带有“password”类型的HTML “input”标记,如下:
请注意,默认情况下,密码值不会显示。如果您确实需要显示密码值,请将“showPassword”属性的值设置为true,如下所示:
此标记呈现HTML“select”元素,它支持数据绑定到所选选项以及使用嵌套选项和标记。示例如下:
选择一个Skill,则可能HTML代码如下:
此标记呈现HTML “option”,它根据绑定值设置“selected”,如下:
如果选择了 “Gryffindor”,则相应的代码如下:
此标记呈现HTML 'option'标记的列表,它根据绑定值设置“selected”属性,如下:
实际生成的HTML代码有可能是这样:
此标记呈现HTML “textarea”,如下:
此标记使用绑定值呈现类型为“hidden”的HTML“input”标记,如下:
此标记在HTML “span”标记中呈现字段错误,它可以访问控制器中创建的错误或由与控制器关联的任何验证器创建的错误。假设我们希望在提交表单后显示firstName和lastName字段的所有错误消息,有一个名为UserValidator的User类实例的验证器,如下:
form.jsp 代码如下:
如果firstName和lastName字段中有一个为空,那么提交后的是HTML是这样:
如果想显示给定页面的整个错误列表怎么办? 下面的示例显示errors标记还支持一些基本的通配符功能。path=“*”显示所有错误; path=“lastName”显示与lastName字段关联的所有错误; 仅显示对象错误。下面的示例将在页面顶部显示错误列表,然后是字段旁边的特定错误:
生成的HTML代码如下:
从Spring 3开始,Spring表单标记库允许输入动态属性,这意味着可以输入任何HTML5特定属性。在Spring 3.1中,表单输入标记支持输入“text”以外的type属性。这旨在允许呈现新的HTML5特定输入类型,例如“email”,“date”,“range”等。请注意,不需要输入type='text',因为'text'是默认类型。
文主要分享了对整合jsp的springboot项目打jar包,如何正确的配置maven pom。
1.pom.xml添加spring-boot-maven-plugin配置
如果只是普通的项目打包,上面的配置足够了,但是带src/main/webapp的打包,还不行,会发现src/main/webapp的内容都没有打进jar包
2.pom.xml添加配置resources配置
这个配置可将src/main/webapp打包到jar包中,但是这个jar包还不能让jsp正常访问
注:如果没有配置<targetPath>META-INF/resources</targetPath>,src/main/webapp的内容会保存到BOOT-INF/ 目录下。经测试,jsp页面无法正常访问,需要指定到META-INF/resources才能正常访问
3.spring-boot-maven-plugin的版本指定为1.4.2.RELEASE
springboot官方推荐的前端模板引擎是thymeleaf,所以对于jsp的支持可能存在兼容性。1.4.2.RELEASE是经过测试出来。具体原因未知,不过确实可用。
如果项目中没有多个main方法,mainClass可以不配置
4.最终版配置
怎么样?如果你觉得有用的话,还不快快收藏起来!!!
附:涉及的代码目录
gitee:https://gitee.com/jq_di/springcloud-template
*请认真填写需求信息,我们会在24小时内与您取得联系。