Spring Framework 5 中的新特性

https://www.ibm.com/developerworks/cn/java/j-whats-new-in-spring-framework-5-theedom/index.html

Spring 5 于 2017 年 9 月发布了通用版本 (GA),它标志着自 2013 年 12 月以来第一个主要 Spring Framework 版本。它提供了一些人们期待已久的改进,还采用了一种全新的编程范例,以反应式宣言中陈述的反应式原则为基础。

这个版本是很长时间以来最令人兴奋的 Spring Framework 版本。Spring 5 兼容 Java™8 和 JDK 9,它集成了反应式流,以便提供一种颠覆性方法来实现端点和 Web 应用程序开发。

诚然,反应式编程不仅是此版本的主题,还是令许多开发人员激动不已的重大特性。人们对能够针对负载波动进行无缝扩展的灾备和响应式服务的需求在不断增加,Spring 5 很好地满足了这一需求。

本文将全面介绍 Spring 5。我将介绍 Java SE 8 和 Java EE 7 API 的基准升级、Spring 5 的新反应式编程模型、HTTP/2 支持,以及 Spring 通过 Kotlin 对函数式编程的全面支持。我还会简要介绍测试和性能增强,最后介绍对 Spring 核心和容器的一般性修订。

升级到 Java SE 8 和 Java EE 7

直到现在,Spring Framework 仍支持一些弃用的 Java 版本,但 Spring 5 已从旧包袱中解放出来。为了充分利用 Java 8 特性,它的代码库已进行了改进,而且该框架要求将 Java 8 作为最低的 JDK 版本。

Spring 5 在类路径(和模块路径)上完全兼容 Java 9,而且它通过了 JDK 9 测试套件的测试。对 Java 9 爱好者而言,这是一条好消息,因为在 Java 9 发布后,Spring 能立即使用它。

在 API 级别上,Spring 5 兼容 Java EE 8 技术,满足对 Servlet 4.0、Bean Validation 2.0 和全新的 JSON Binding API 的需求。对 Java EE API 的最低要求为 V7,该版本引入了针对 Servlet、JPA 和 Bean Validation API 的次要版本。

反应式编程模型

Spring 5 最令人兴奋的新特性是它的反应式编程模型。Spring 5 Framework 基于一种反应式基础而构建,而且是完全异步和非阻塞的。只需少量的线程,新的事件循环执行模型就可以垂直扩展。

该框架采用反应式流来提供在反应式组件中传播负压的机制。负压是一个确保来自多个生产者的数据不会让使用者不堪重负的概念。

Spring WebFlux 是 Spring 5 的反应式核心,它为开发人员提供了两种为 Spring Web 编程而设计的编程模型:一种基于注解的模型和 Functional Web Framework (WebFlux.fn)。

基于注解的模型是 Spring WebMVC 的现代替代方案,该模型基于反应式基础而构建,而 Functional Web Framework 是基于@Controller 注解的编程模型的替代方案。这些模型都通过同一种反应式基础来运行,后者调整非阻塞 HTTP 来适应反应式流 API。

使用注解进行编程

WebMVC 程序员应该对 Spring 5 的基于注解的编程模型非常熟悉。Spring 5 调整了 WebMVC 的 @Controller 编程模型,采用了相同的注解。

在清单 1 中,BookController 类提供了两个方法,分别响应针对某个图书列表的 HTTP 请求,以及针对具有给定 id 的图书的 HTTP 请求。请注意 resource 方法返回的对象(Mono 和 Flux)。这些对象是实现反应式流规范中的 Publisher 接口的反应式类型。它们的职责是处理数据流。Mono 对象处理一个仅含 1 个元素的流,而 Flux 表示一个包含 N 个元素的流。

清单 1. 反应式控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
public class BookController {
    @GetMapping("/book")
    Flux<Book> list() {
        return this.repository.findAll();
    }
    @GetMapping("/book/{id}")
    Mono<Book> findById(@PathVariable String id) {
        return this.repository.findOne(id);
    }
    // Plumbing code omitted for brevity
}

这是针对 Spring Web 编程的注解。现在我们使用函数式 Web 框架来解决同一个问题。

函数式编程

Spring 5 的新函数式方法将请求委托给处理函数,这些函数接受一个服务器请求实例并返回一种反应式类型。清单 2 演示了这一过程,其中 listBook 和 getBook 方法类似于清单 1 中的功能。

清单 2. 清单 2.BookHandler 函数类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class BookHandler {
    public Mono<ServerResponse> listBooks(ServerRequest request) {
        return ServerResponse.ok()
            .contentType(APPLICATION_JSON)
            .body(repository.allPeople(), Book.class);
    }
     
    public Mono<ServerResponse> getBook(ServerRequest request) {
        return repository.getBook(request.pathVariable("id"))
            .then(book -> ServerResponse.ok()
            .contentType(APPLICATION_JSON)
            .body(fromObject(book)))
            .otherwiseIfEmpty(ServerResponse.notFound().build());
    }
    // Plumbing code omitted for brevity
}

通过路由函数来匹配 HTTP 请求谓词与媒体类型,将客户端请求路由到处理函数。清单 3 展示了图书资源端点 URI 将调用委托给合适的处理函数:

清单 3. Router 函数
1
2
3
4
5
6
7
8
9
BookHandler handler = new BookHandler();
RouterFunction<ServerResponse> personRoute =
    route(
        GET("/books/{id}")
        .and(accept(APPLICATION_JSON)), handler::getBook)
        .andRoute(
    GET("/books")
        .and(accept(APPLICATION_JSON)), handler::listBooks);

这些示例背后的数据存储库也支持完整的反应式体验,该体验是通过 Spring Data 对反应式 Couchbase、Reactive MongoDB 和 Cassandra 的支持来实现的。

使用 REST 端点执行反应式编程

新的编程模型脱离了传统的 Spring WebMVC 模型,引入了一些很不错的新特性。

举例来说,WebFlux 模块为 RestTemplate 提供了一种完全非阻塞、反应式的替代方案,名为 WebClient。清单 4 创建了一个 WebClient,并调用 books 端点来请求一本给定 id 为 1234 的图书。

清单 4. 通过 WebClient 调用 REST 端点
1
2
3
4
5
6
Mono<Book> book = WebClient.create("http://localhost:8080")
      .get()
      .url("/books/{id}", 1234)
      .accept(APPLICATION_JSON)
      .exchange(request)
      .then(response -> response.bodyToMono(Book.class));

HTTP/2 支持

Spring Framework 5.0 将提供专门的 HTTP/2 特性支持,还支持人们期望出现在 JDK 9 中的新 HTTP 客户端。尽管 HTTP/2 的服务器推送功能已通过 Jetty servlet 引擎的 ServerPushFilter 类向 Spring 开发人员公开了很长一段时间,但如果发现 Spring 5 中开箱即用地提供了 HTTP/2 性能增强,Web 优化者们一定会为此欢呼雀跃。

Java EE Servlet 规范预计将于 2017 年第 4 季度发布,Servlet 4.0 支持将在 Spring 5.1 中提供。到那时,HTTP/2 特性将由 Tomcat 9.0、Jetty 9.3 和 Undertow 1.4 原生提供。

Kotlin 和 Spring WebFlux

Kotlin 是一种来自 JetBrains 的面向对象的语言,它支持函数式编程。它的主要优势之一是与 Java 有非常高的互操作性。通过引入对 Kotlin 的专门支持,Spring 在 V5 中全面吸纳了这一优势。它的函数式编程风格与 Spring WebFlux 模块完美匹配,它的新路由 DSL 利用了函数式 Web 框架以及干净且符合语言习惯的代码。可以像清单 5 中这样简单地表达端点路由:

清单 5. Kotlin 的用于定义端点的路由 DSL
1
2
3
4
5
6
7
8
9
10
11
12
13
@Bean
fun apiRouter() = router {
    (accept(APPLICATION_JSON) and "/api").nest {
        "/book".nest {
            GET("/", bookHandler::findAll)
            GET("/{id}", bookHandler::findOne)
        }
        "/video".nest {
            GET("/", videoHandler::findAll)
            GET("/{genre}", videoHandler::findByGenre)
        }
    }
}

使用 Kotlin 1.1.4+ 时,还添加了对 Kotlin 的不可变类的支持(通过带默认值的可选参数),以及对完全支持 null 的 API 的支持。

使用 Lambda 表达式注册 bean

作为传统 XML 和 JavaConfig 的替代方案,现在可以使用 lambda 表达式注册 Spring bean,使 bean 可以实际注册为提供者。清单 6 使用 lambda 表达式注册了一个 Book bean。

清单 6. 将 Bean 注册为提供者
1
2
3
4
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Book.class, () -> new
              Book(context.getBean(Author.class))
        );

Spring WebMVC 支持最新的 API

全新的 WebFlux 模块提供了许多新的、令人兴奋的功能,但 Spring 5 也迎合了愿意继续使用 Spring MVC 的开发人员的需求。Spring 5 中更新了模型-视图-控制器框架,以兼容 WebFlux 和最新版的 Jackson 2.9 和 Protobuf 3.0,甚至包括对新的 Java EE 8 JSON-Binding API 的支持。

除了 HTTP/2 特性的基础服务器实现之外,Spring WebMVC 还通过 MVC 控制器方法的一个参数来支持 Servlet 4.0 的 PushBuilder。最后,WebMVC 全面支持 Reactor 3.1 的 Flux 和 Mono 对象,以及 RxJava 1.3 和 2.1,它们被视为来自 MVC 控制器方法的返回值。这项支持的最终目的是支持 Spring Data 中的新的反应式 WebClient 和反应式存储库。

使用 JUnit 5 执行条件和并发测试

Spring 5 的测试套件通过多种方式得到了增强,但最明显的是它对 JUnit 5 的支持。现在可以在您的单元测试中利用 Java 8 中提供的函数式编程特性。清单 7 演示了这一支持:

清单 7. 清单 7.JUnit 5 全面接纳了 Java 8 流和 lambda 表达式
1
2
3
4
5
6
7
@Test
void givenStreamOfInts_SumShouldBeMoreThanFive() {
    assertTrue(Stream.of(20, 40, 50)
      .stream()
      .mapToInt(i -> i)
      .sum() > 110, () -> "Total should be more than 100");
}

Spring 5 继承了 JUnit 5 在 Spring TestContext Framework 内实现多个扩展 API 的灵活性。举例而言,开发人员可以使用 JUnit 5 的条件测试执行注解 @EnabledIf 和 @DisabledIf 来自动计算一个 SpEL (Spring Expression Language) 表达式,并适当地启用或禁用测试。借助这些注解,Spring 5 支持以前很难实现的复杂的条件测试方案。Spring TextContext Framework 现在能够并发执行测试。

使用 Spring WebFlux 执行集成测试

Spring Test 现在包含一个 WebTestClient,后者支持对 Spring WebFlux 服务器端点执行集成测试。WebTestClient 使用模拟请求和响应来避免耗尽服务器资源,并能直接绑定到 WebFlux 服务器基础架构。

WebTestClient 可绑定到真实的服务器,或者使用控制器或函数。在清单 8 中,WebTestClient 被绑定到 localhost:

清单 8. 绑定到 localhost 的 WebTestClient
1
2
3
4
WebTestClient testClient = WebTestClient
  .bindToServer()
  .baseUrl("http://localhost:8080")
  .build();

在清单 9 中,测试了 RouterFunction

清单 9. 将 WebTestClient 绑定到 RouterFunction
1
2
3
4
5
6
7
8
9
10
11
RouterFunction bookRouter = RouterFunctions.route(
  RequestPredicates.GET("/books"),
  request -> ServerResponse.ok().build()
);
  
WebTestClient
  .bindToRouterFunction(bookRouter)
  .build().get().uri("/books")
  .exchange()
  .expectStatus().isOk()
  .expectBody().isEmpty();

包清理和弃用

Spring 5 中止了对一些过时 API 的支持。遭此厄运的还有 Hibernate 3 和 4,为了支持 Hibernate 5,它们遭到了弃用。另外,对 Portlet、Velocity、JasperReports、XMLBeans、JDO 和 Guava 的支持也已中止。

包级别上的清理工作仍在继续:Spring 5 不再支持 beans.factory.accessjdbc.support.nativejdbcmock.staticmock(来自 spring-aspects 模块)或 web.view.tiles2M。Tiles 3 现在是 Spring 的最低要求。

对 Spring 核心和容器的一般更新

Spring Framework 5 改进了扫描和识别组件的方法,使大型项目的性能得到提升。目前,扫描是在编译时执行的,而且向 META-INF/spring.components 文件中的索引文件添加了组件坐标。该索引是通过一个为项目定义的特定于平台的应用程序构建任务来生成的。

标有来自 javax 包的注解的组件会添加到索引中,任何带 @Index 注解的类或接口都会添加到索引中。Spring 的传统类路径扫描方式没有删除,而是保留为一种后备选择。有许多针对大型代码库的明显性能优势,而托管许多 Spring 项目的服务器也会缩短启动时间。

Spring 5 还添加了对 @Nullable 的支持,后者可用于指示可选的注入点。使用者现在必须准备接受 null 值。此外,还可以使用此注解来标记可以为 null 的参数、字段和返回值。@Nullable 主要用于 IntelliJ IDEA 等 IDE,但也可用于 Eclipse 和 FindBugs,它使得在编译时处理 null 值变得更方便,而无需在运行时发送 NullPointerExceptions

Spring Logging 还提升了性能,自带开箱即用的 Commons Logging 桥接器。现在已通过资源抽象支持防御性编程,为 getFile访问提供了 isFile 指示器。

结束语

Spring 5 的首要特性是新的反应式编程模型,这代表着对提供可无缝扩展、基于 Spring 的响应式服务的重大保障。随着人们对 Spring 5 的采用,开发人员有望看到反应式编程将会成为使用 Java 语言的 Web 和企业应用程序开发的未来发展道路。

未来的 Spring Framework 版本将继续反映这一承诺,因为 Spring Security、Spring Data 和 Spring Integration 有望采用反应式编程的特征和优势。

总之,Spring 5 代表着一次大受 Spring 开发人员欢迎的范例转变,同时也为其他框架指出了一条发展之路。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/538852.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么计算一组数据的波动_税控盘数据和小规模增值税申报表计算结果不一致怎么办...

a公司为小规模纳税人&#xff0c;于2020年1月申报2019年第四季度增值税时&#xff0c;是按照金税盘的数据实际销售金额为562,563,13元&#xff0c;实际销售税额为16,876.87元填写小规模纳税人增值税申报表。申报成功后&#xff0c;税务系统却跳出比对异常&#xff0c;户管员要求…

简单又好看的按钮,扁平化按钮。

原文地址&#xff1a;http://blog.csdn.net/peijiangping1989/article/details/19333779 点击阅读原文 ----------------------------------------------------------- 今天分享一下流行的扁平化按钮。完全不需要用到图片哦。效果图如下&#xff1a; 里面有2个按钮都是一样的…

python输入三行、能出来三行数据_python 读入多行数据的实例

一、前言本文主要使用python 的raw_input() 函数读入多行不定长的数据&#xff0c;输入结束的标志就是不输入数字情况下直接回车&#xff0c;并填充特定的数作为二维矩阵二、代码def get2dlistdata():res []inputline raw_input() #以字符串的形式读入一行#如果不为空字符串作…

请问,现在android流行什么开源框架?

retrofit2.0RxjavagreenDao3大流行图片库p,g,f&#xff08;Picasso&#xff0c;Fresco&#xff0c;Glide&#xff09; 3分钟全面了解Android主流图片加载库 http://blog.csdn.net/carson_ho/article/details/51939774 Retrofit2使用&#xff08;非常简洁易懂&#xff09; ht…

matlab 锐化降噪,matlab 图形锐化 滤波

help imreadhelp fspecial imfilt帮助稳定中有较多的示例fspecial 函数功能&#xff1a;产生预定义滤波器格式&#xff1a;Hfspecial(type)Hfspecial(gaussian,n,sigma) 高斯低通滤波器Hfspecial(sobel) Sobel 水平边缘增强滤波器Hfspecial…

执行 link.exe 时出错_在20多岁时应该做什么,以避免在30多岁和40多岁时后悔?...

1. 永远不要以为自己可以&#xff0c;将会或曾经到达过以为是错误的。无论是幸福&#xff0c;收入还是心态。在二十多岁的关键时期&#xff0c;我有这种心态&#xff0c;对我自己不利。认为自己“实现”是一种静态的世界观&#xff0c;阻碍了您的成长。接受这样的事实&#xff…

音频自动增益 与 静音检测 算法 附完整C代码

前面分享过一个算法《音频增益响度分析 ReplayGain 附完整C代码示例》 主要用于评估一定长度音频的音量强度&#xff0c; 而分析之后&#xff0c;很多类似的需求&#xff0c;肯定是做音频增益&#xff0c;提高音量诸如此类做法。 不过在项目实测的时候&#xff0c;其实真的很难…

python绘制饼状图图例_使用matplotlib的所有饼图的通用图例

图例只需调用一次&#xff0c;否则将显示7个不同的图例。我在下面展示了一个例子。请注意&#xff0c;您必须将自己的数据替换为ax.pie()&#xff1a;data1 (10,90) # some data to be plotted data2 (40,50) data3 (70,30) labels [Sending Data, Not Sending Data] #lege…

Android初始化本地数据库

原文&#xff1a;http://blog.csdn.net/itjavawfc/article/details/50860647 点击阅读原文 -------------------------------- 最近遇到一个需求&#xff0c;一个同学不会搭服务器&#xff0c;但是Android课程设计需要用到很多数据&#xff0c;这样就出现了一个问题&#xff0c…

jsp springmvc 视图解析器_springMVC配置jsp/html视图解析器

1、maven项目引入freemark相关jar包freemaker是以个模板引擎&#xff0c;可以根据提供的数据和创建好的模板,去自动的创建html静态页面。所以在返回html视图时可以用这个引擎结合数据生成html静态页面。org.springframeworkspring-context-support5.0.7.RELEASEorg.freemarkerf…

php设计模式原型模式,原型模式_设计模式_设计模式之原型模式 - Lane Blog

108Clicks: 6614 Date: 2014-04-21 21:48:35 Power By 李轩Lane原型模式提取重复功能&#xff0c;避免了程序员喜欢复制粘贴的坏习惯。设计模式中的原型模式就是&#xff0c;用原型实例指定创建对象的重力&#xff0c;通过拷贝这些原型来创建新的对象从一个对象再创建另外一个可…

Windows2003如何安装IIS和ftp

【开始】----【控制面板】----【添加或删除程序】 出现如下“添加或删除程序”界面&#xff0c;点击“添加/删除windows组件&#xff08;a&#xff09; ” 出现如下“window组件向导”界面 下拉“组件”栏目条&#xff0c;选择“应用程序服务器” 点击“应用程序服务器”下的“…

hadoop临时文件 jar包_hadoop之Mapper/reducer源码分析之二

若当前JobClient (0.22 hadoop) 运行在YARN.则job提交任务运行在YARNRunnerHadoop Yarn 框架原理及运作机制主要步骤作业提交作业初始化资源申请与任务分配任务执行具体步骤在运行作业之前&#xff0c;Resource Manager和Node Manager都已经启动&#xff0c;所以在上图中&#…

ANDROID:SHOWASACTION="NEVER"是做什么用的?

原文地址&#xff1a;http://www.cnblogs.com/android-joker/p/4478491.html 点击阅读原文 --------------------------------------------------------- 安卓开发项目文件中有一个目录叫做menu&#xff0c;里面有tybmain.xml item选项里有一句 android:showAsAction "…

吴恩达ex3_Wu-Enda机器学习编程作业Python实现EX3,吴恩达,machinelearning,python,ex3nn

# -*- coding: utf-8 -*-"""Created on Wed Jul 1 20:28:57 2020author: cheetah023"""import numpy as npimport matplotlib.pyplot as pltimport scipy.io as sciimport random as ra#函数定义def sigmoid(X):return 1 /(1 np.exp(-X))def pr…

php数组验证用户名密码,求个php数组验证问题,在线等

现在有这么一个数组,是属性表Array([0] > Array([list_attr_id] > 30[list_attr_name] > 颜色[list_attr_attr] > 黑色|白色|金色[list_attr_price] > 0|10.1|20[list_attr_shop_id] > 28)[1] > Array([list_attr_id] > 31[list_attr_name] > 规格[…

基于python的视频监控系统_Python实现微信监控报警系统

概述: 本文主要分享一下博主在学习wxpy 的过程中开发的一个小程序。博主在最近有一个监控报警的需求需要完成&#xff0c;然后刚好在学习wxpy 这个东西&#xff0c;因此很巧妙的将工作和学习联系在一起。 博文中主要使用到的技术设计到Python&#xff0c;Redis&#xff0c;以及…

python 编码文件json.loads json.dumps

python 编码文件json.loads json.dumps import yaml d {name: 张三, age: 1} print d jd json.dumps(d, ensure_asciiFalse, encodingutf-8)) ud json.loads(jd, encodingutf-8) print ud ud yaml.safe_load(jd, encodingutf-8) print udposted on 2018-04-23 15:18 秦瑞It…

getActionBar()报空指针异常

调用 getActionBar()的Activity类 public class WlanListActivity extends AppCompatActivity 在使用getActionBar("标题内容")的时候报空指针。 原因是要用AppCompatActivity类里的getSupportActionBar()

python 类中定义列表_Python3中的自定义列表类,具有

我想用python3编写一个自定义列表类&#xff0c;就像在这个问题How would I create a custom list class in python?中一样&#xff0c;但与该问题不同&#xff0c;我想实现__get__和{}方法。虽然我的类与list类似&#xff0c;但是这些方法背后隐藏着一些神奇的操作。所以我想…