相关内容:
架构师系列内容:架构师学习笔记(持续更新)

Spring5 新特性简述

Spring 5 于 2017 年 9 月发布了通用版本 (GA),它标志着自 2013 年 12 月以来第一个主要Spring Framework 版本。它提供了一些人们期待已久的改进,还采用了一种全新的编程范例,以反应式描述中陈述的反应式原则为基础。
这个版本是很长时间以来最令人激动的 Spring Framework 版本。Spring 5 兼容 Java™8 和 JDK 9,它集成了反应式流,以方便后续提供一种颠覆性方法来实现端点和 Web 应用程序开发。当然,反应式编程不仅是此版本的主题,还是令许多程序员激动不已的重大特性。人们对能够针对负载波动进行无缝扩展的容灾和响应式服务的需求在不断增加,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 测试套件的测试。对 Java9 爱好者而言,这是一条好消息,因为在 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 的现代替代方案,该模型基于反应式基础而构建,而 FunctionalWeb Framework 是基于 @Controller 注解的编程模型的替代方案。这些模型都通过同一种反应式基础来运行,后者调整非阻塞 HTTP 来适应反应式流 API。

1、使用注解进行编程
Web MVC 程序员应该对 Spring 5 的基于注解的编程模型非常熟悉。Spring 5 调整了 Web MVC的 @Controller 编程模型,采用了相同的注解。
在下面的代码中 BookController 类提供了两个方法,分别响应针对某个图书列表的 HTTP 请求,以及针对具有给定 id 的图书的 HTTP 请求。请注意 resource 方法返回的对象(Mono 和 Flux)。这些对象是实现反应式流规范中的 Publisher 接口的反应式类型。它们的职责是处理数据流。Mono 对象处理一个仅含 1 个元素的流,而 Flux 表示一个包含 N 个元素的流。

@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);}
}

这是针对 Spring Web 编程的注解。现在我们使用函数式 Web 框架来解决同一个问题。
2、支持函数式编程
Spring 5 的新函数式方法将请求委托给处理函数,这些函数接受一个服务器请求实例并返回一种反应式类型。来看一段代码,创建 BookHandler 类,其中 listBook() 和 getBook() 方法相当于 Controller中的功能。

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());}
}

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

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 的支持来实现的。
3、使用 REST 端点执行反应式编程
新的编程模型脱离了传统的 Spring WebMVC 模型,引入了一些很不错的新特性。举例来说,WebFlux 模块为 RestTemplate 提供了一种完全非阻塞、反应式的替代方案,名为WebClient。下面创建一个 WebClient,并调用 books 端点来请求一本给定 id 为 1234 的图书。通过 WebClient 调用 REST 端点。

Mono<Book> book = WebClient.create("http://localhost:8080").get().url("/books/{id}", 1234).accept(APPLICATION_JSON).exchange(request).then(response -> response.bodyToMono(Book.class));

4、对 HTTP/2 支持
HTTP/2 幕后原理:要了解 HTTP/2 如何提高传输性能,减少延迟,并帮助提高应用程序吞吐量,从而提供经过改进的丰富 Web 体验。
Spring Framework 5.0 提供专门的 HTTP/2 特性支持,还支持人们期望出现在 JDK 9 中的新 HTTP客户端。尽管 HTTP/2 的服务器推送功能已通过 Jetty Servlet 引擎的 ServerPushFilter 类向Spring 开发人员公开了很长一段时间,但如果发现 Spring 5 中开箱即用地提供了 HTTP/2 性能增强,Web 优化者们一定会为此欢呼雀跃。
Servlet 4.0 支持在 Spring 5.1 中提供。到那时,HTTP/2 新特性将由 Tomcat 9.0、Jetty 9.3 和Undertow 1.4 原生提供。

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

@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 的支持。

6、使用 Lambda 表达式注册 Bean
作为传统 XML 和 JavaConfig 的替代方案,现在可以使用 lambda 表达式注册 Spring bean,使bean 可以实际注册为提供者。下面代码中使用 lambda 表达式注册了一个 Book bean。将 Bean 注册为提供者。

GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Book.class, () -> newBook(context.getBean(Author.class))
);

7、Spring Web MVC 支持最新的 API
全新的 WebFlux 模块提供了许多新的、令人兴奋的功能,但 Spring 5 也迎合了愿意继续使用 SpringMVC 的开发人员的需求。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 和反应式存储库。

8、使用 JUnit 5 执行条件和并发测试
JUnit 和 Spring 5:Spring 5 全面接纳了函数式范例,并支持 JUnit 5 及其新的函数式测试风格。还提供了对 JUnit 4 的向后兼容性,以确保不会破坏旧代码。
Spring 5 的测试套件通过多种方式得到了增强,但最明显的是它对 JUnit 5 的支持。现在可以在您的单元测试中利用 Java 8 中提供的函数式编程特性。以下代码演示了这一支持:JUnit 5 全面接纳了 Java 8 流和 lambda 表达式。

@Test
void givenStreamOfInts_SumShouldBeMoreThanFive() {assertTrue(Stream.of(20, 40, 50).stream().mapToInt(i -> i).sum() > 110, () -> "Total should be more than 100");
}

迁移到 JUnit 5:如果您对升级到 JUnit 5 持观望态度,Steve Perry 的分两部分的深入剖析教程将说服您冒险尝试。
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 可绑定到真实的服务器,或者使用控制器或函数。在下面的代码中,WebTestClient 被绑定到 localhost:
绑定到 localhost 的 WebTestClient

WebTestClient testClient = WebTestClient.bindToServer().baseUrl("http://localhost:8080").build();

将 WebTestClient 绑定到 RouterFunction

RouterFunction bookRouter = RouterFunctions.route(RequestPredicates.GET("/books"),request -> ServerResponse.ok().build()
);
WebTestClient.bindToRouterFunction(bookRouter).build().get().uri("/books").exchange().expectStatus().isOk().expectBody().isEmpty();

9、包清理和弃用
Spring 5 中止了对一些过时 API 的支持。遭此厄运的还有 Hibernate 3 和 4,为了支持 Hibernate5,它们遭到了弃用。另外,对 Portlet、Velocity、JasperReports、XMLBeans、JDO 和 Guava 的支持也已中止。
包级别上的清理工作仍在继续:Spring 5 不再支持 beans.factory.access、jdbc.support.nativejdbc、mock.staticmock(来自 spring-aspects 模块)或 web.view.tiles2M。Tiles 3 现在是 Spring 的最低要求。

10、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 指示器。

11、我如何看 Spring5?
Spring 5 的首要特性是新的反应式编程模型,这代表着对提供可无缝扩展、基于 Spring 的响应式服务的重大保障。随着人们对 Spring 5 的采用,开发人员有望看到反应式编程将会成为使用 Java 语言的 Web 和企业应用程序开发的未来发展道路。
未来的 Spring Framework 版本将继续体现这一承诺,因为 Spring Security、Spring Data 和Spring Integration 有望采用反应式编程的特征和优势。
总之,Spring 5 代表着一次大受 Spring 开发人员欢迎的华丽转变,同时也为其他框架指出了一条发展之路。Spring5 的升级也为 Spring Boot、Spring Cloud 提供非常丰富的经验,Spring 不仅仅只是一个框架,已然成为了一种编程生态。

Spring5的几个新特性相关推荐

  1. spring5新特性

    1 使用 lambda表达式定义bean 2 日志 spring4的日志是用jcl,原生的JCL,底层通过循环去加载具·体的日志实现技术,所以有先后顺序,spring5利用的是spring-jcl,其 ...

  2. spring5新特性的介绍

    Spring5的新特性 与JDK相关的升级 jdk版本要求: spring5.0在2017年9月发布了它的GA(通用)版本.该版本是基于jdk8编写的,所以jdk8以下版本将无法使用.同时,可以兼容j ...

  3. Spring5 新特性

    Spring5 新特性 Spring 5于2017年底发布.Spring 5为Spring框架带来了大量更新.Spring 4于2013年发布,因此每个人都期待对该框架进行重大改革.我很高兴看到Spr ...

  4. java day60【 Spring 中的 JdbcTemplate[会用] 、Spring 中的事务控制 、Spring5 的新特性[了解] 】...

    第1章 Spring 中的 JdbcTemplate[会用] 1.1JdbcTemplate 概述 1.2JdbcTemplate 对象的创建 1.3spring 中配置数据源 1.3.1 环境搭建 ...

  5. JDK10的新特性:var泛型和多个接口实现

    文章目录 简介 实现多个接口 使用多个接口 使用var 总结 简介 在JDK10的新特性:本地变量类型var中我们讲到了为什么使用var和怎么使用var. 今天我们来深入的考虑一下var和泛型,多个接 ...

  6. JDK11的新特性:HTTP API和reactive streams

    文章目录 简介 怎么在java中使用reactive streams POST请求的例子 总结 简介 在JDK11的新特性:新的HTTP API中,我们介绍了通过新的HTTP API,我们可以发送同步 ...

  7. JDK11的新特性:新的HTTP API

    文章目录 简介 使用HTTP Client请求的基本流程 创建HTTP Client 创建HTTP Request 发送HTTP请求 异步HTTP请求 总结 JDK11的新特性:新的HTTP API ...

  8. JDK12的新特性:CompactNumberFormat

    文章目录 简介 CompactNumberFormat详解 自定义CompactNumberFormat 解析CompactNumber 总结 JDK12的新特性:CompactNumberForma ...

  9. JDK12的新特性:teeing collectors

    文章目录 简介 talk is cheap, show me the code Teeing方法深度剖析 Characteristics 总结 JDK12的新特性:teeing collectors ...

最新文章

  1. 12.6%!IJCAI 2020接收率断崖式下跌,但还是有华人大佬中了三篇
  2. (转载)TL-WN725N V3无线网卡驱动移植与wireless工具wpa_supplicant-2.6
  3. 什么是透传通道?(透明传输通道,就是当中继使)
  4. 第三次学JAVA再学不好就吃翔(part64)--自动装箱和自动拆箱
  5. 10分钟Get拥抱无服务的正确姿势
  6. 一文说清ZooKeeper的实现原理
  7. nginx 实现Web应用程序的负载均衡
  8. 采集gpu_GPU是怎么处理游戏画面?一文看懂显卡的工作原理,原来这么简单
  9. 使用pgd和fgsm方法进行攻击并使用map方法评估
  10. NA Express
  11. ImageJ的安装与简单使用
  12. android 去广告浏览器,手机去广告浏览器Adblock Plus Browser
  13. Win7旗舰版下安装SQL Server 2008总结
  14. 尼尔·斯蒂芬森 (Neal Stephenson) 谈他的新地球工程气候变化惊悚片并创造了“元宇宙”一词...
  15. 技术探秘:华为云瑶光何以定方向
  16. imx6ull:uboot的make xxx_defconfig 过程分析
  17. 一阶微分电路和积分电路有何功能
  18. set的三种遍历方式-----不能用for循环遍历(无序)
  19. 学 习 中 的 思 考
  20. SQL Server 学习笔记——T-SQL

热门文章

  1. java集合类详解_【Java入门提高篇】Day20 Java集合类详解(三)List接口
  2. 两个table怎么对齐_Origin教程|“师兄,图表坐标轴下的分组表格是怎么添加的?”...
  3. 算法列表-java实现
  4. 软件工程实践专题第三次团队作业
  5. hibernate框架(二)核心配置API
  6. Java中的非对称加密算法RSA实现
  7. Mybatis缓存模块(一)BlockingCache
  8. 纳米丸穿透癌细胞(癌症)
  9. Edge 浏览器有秘密白名单,允许 Facebook 运行 Flash 代码
  10. 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(1月9日-1月15日)