Spring5于2017年9月发布,正式发布(GA),标志着自2013年12月以来的第一个主要Spring框架发布。它提供了期待已久的改进,并采用了一种新的编程范式,该范式基于反应性宣言中提出的反应性原则。
这个版本是Spring框架长期以来最激动人心的版本。与Java兼容™ spring5集成了jdk8和jdk9,为端点和web应用程序开发提供了一种改变游戏规则的方法。
事实上,反应式编程是本次发布的主题,也是许多开发人员热衷的标题特性。它很好地适应了不断增长的对弹性和响应性服务的需求,这些服务可以无缝地扩展以适应不断变化的负载。
本文展示了Spring5的特性,介绍了对JavaSE8和JavaEE7API的基线升级,Spring5新的反应式编程模型,HTTP/2支持,以及Spring对Kotlin函数式编程的完全支持。我还简要介绍了测试和性能增强,并以Spring核心和容器的一般性修订作为结束。
升级至Java SE 8 和 Java EE 7
到目前为止,Spring框架还支持不推荐的Java版本,但是spring5已经从遗留的包袱中解放出来了。它的代码库已经过修改,以利用java8的特性,并且该框架需要java8作为最低的JDK版本。
spring5在类路径和模块路径上与java9完全兼容,并通过了jdk9测试套件。这对Java9的粉丝来说是个好消息,因为一旦Java9发布,Spring就可以运行了。
在API级别,Spring5与JavaEE8技术兼容,并满足Servlet4.0、BeanValidation 2.0和全新的JSON绑定API的要求。JavaEEAPI的最低要求是Version7,它为Servlet、JPA和Bean验证API引入了次要版本。
反应式规划模型
Spring5最令人兴奋的新特性是它的反应式编程模型。Spring 5框架是建立在反应基础上的,完全异步和非阻塞。新的事件循环执行模型可以垂直扩展,只需要少量线程。
该框架采用反应流来提供一种在反应元件管道中传递背压的机制。背压是一个确保消费者不会被来自多个生产商的数据淹没的概念。
Spring WebFlux是spring5的反应式核心,它为开发人员提供了两种为springweb编程设计的编程模型:基于注释的模型和功能性web框架(WebFlux.fn)。
基于注释的模型是Spring WebMVC的现代替代方案,它建立在被动的基础上,而功能性Web框架是基于@Controller
注释的编程模型的替代方案。这些模型运行在相同的反应性基础上,从而使非阻塞HTTP与反应性流API相适应。
使用注释编程
spring5基于注释的编程模型应该让WebMVC程序员非常熟悉。spring5采用了WebMVC的@Controller
编程模型,并使用了相同的注释。
在清单1中,BookController
类提供了两个方法,它们响应HTTP请求,请求一个图书列表和一个具有给定id的图书。这些是从反应流规范实现发布者接口的反应类型。它们的作用是处理数据流。Mono
对象处理一个元素流,而Flux
表示N个元素流。
清单1.Reactive控制器
@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
}
这是springweb编程的注释。现在让我们使用功能性web框架来解决同样的问题。
函数式程序设计
Spring5新的函数方法将请求委托给处理函数,处理函数接受服务器请求实例并返回反应类型。清单2中演示了这一点,其中listBook
和getBook
方法与清单1中的功能相呼应。
清单2.BookHandler
函数类
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.路由器函数
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数据对reactive Couchbase、reactive MongoDB和Cassandra的支持来支持完整的reactive体验。
带有REST端点的反应式编程
新的编程模型与传统的springwebmvc模型不同,并带来了一些非常好的新特性。
首先,WebFlux模块提供了一个完全无阻塞的、反应式的rest模板替代品,称为WebClient。清单4创建了一个WebClient并调用books端点来请求一本给定id为1234的书。
清单4.使用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));
HTTP/2支持
Spring Framework 5.0将提供专用的HTTP/2特性支持,以及对JDK 9中预期的新HTTP客户端的支持。虽然HTTP/2的服务器推送特性已经通过Jetty servlet引擎的ServerPushFilter
类向Spring开发人员提供了相当长的一段时间,在Spring5中,Web优化器将高兴地发现HTTP/2的性能增强是现成的。
JavaEEServlet规范预计将在2017年最后一个季度发布,Servlet4.0支持将在Spring5.1中上线。在此之前,HTTP/2特性将由tomcat9.0、jetty9.3和undertow1.4提供。
Kotlin和Spring WebFlux
Kotlin是JetBrains的一种面向对象语言,支持函数式编程。它的主要优点之一是提供了与Java非常好的互操作性。Spring在版本5中通过引入对Kotlin的专门支持,全心全意地支持这一点。它的函数式编程风格是springwebflux模块的理想匹配,它的新路由DSL利用了功能性web框架和干净的惯用代码。端点路由可以简单地表示为如清单5所示:
清单5.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)
}
}
}
在使用kotlin1.1.4+时,添加了对Kotlin的不可变类的支持,这些类带有带默认值的可选参数和完整的空安全api。
用于bean注册的Lambdas
现在可以使用lambdas注册springbean,以替代传统的XML和JavaConfig,从而有效地将bean注册为供应商。清单6使用lambdas注册了一个Book bean。
清单6.Bean注册为supplier
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Book.class, () ‑> new
Book(context.getBean(Author.class))
);
SpringWebMVC对最新API的支持
闪亮的新WebFlux模块提供了许多令人兴奋的新功能,但是spring5也迎合了那些喜欢继续使用springmvc的开发人员。spring5中的model-view-controller
框架已经过更新,可以与WebFlux以及jackson2.9和protobuf3.0的最新版本一起使用,甚至还包括对新的javaee8json绑定API的支持。
除了HTTP/2特性的底层服务器实现之外,SpringWebMVC还通过MVC控制器方法的参数支持Servlet4.0的PushBuilder。最后,WebMVC包括对Reactor 3.1 Flux和Mono对象的完全支持,以及rxjava1.3和2.1,它们被视为MVC控制器方法的返回值。这种支持的目标是Spring数据中新的反应式WebClient和反应式存储库。
JUnit 5的条件和并发测试
Spring5的测试套件在几个方面得到了增强,但最显著的是它对JUnit5的支持。清单7演示了:
清单7.junit5完全包含Java8流和lambda
@Test
void givenStreamOfInts_SumShouldBeMoreThanFive() {
assertTrue(Stream.of(20, 40, 50)
.stream()
.mapToInt(i ‑> i)
.sum() > 110, () ‑> "Total should be more than 100");
}
Spring5支持JUnit5在SpringTestContext框架中实现多个扩展API的灵活性。例如,开发人员可以使用junit5的条件测试执行注释@EnabledIf和@DisabledIf来自动计算SpEL(springexpressionlanguage)表达式,并根据需要启用或禁用测试。通过这些注释,Spring5支持复杂的条件测试场景,而这些场景以前很难实现。springtextcontext框架现在可以并发执行测试。
Spring WebFlux集成测试
Spring测试现在包括一个WebTestClient,它支持springwebflux服务器端点的集成测试。WebTestClient使用模拟请求和响应来避免运行服务器,并且能够直接绑定到WebFlux服务器基础结构。
WebTestClient可以绑定到真正的服务器,或者使用控制器或函数。在清单8中,WebTestClient绑定到localhost:
清单8.WebTestClient绑定到localhost
WebTestClient testClient = WebTestClient
.bindToServer()
.baseUrl("http://localhost:8080")
.build();
在清单9中,测试了一个RouterFunction
:
清单9.将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();
包清理和deprecation
Spring5停止了对一些过时API的支持。Hibernate3和Hibernate4被淘汰,取而代之的是Hibernate5,对Portlet、Velocity、JasperReports、XMLBeans、JDO和Guava的支持也消失了。
Spring5不再支持beans.factory.access
、jdbc.support.nativejdbc
、mock.staticmock
(来自SpringAspects模块)或web.view.tiles2M
。Tiles 3现在是Spring的最低要求。
Spring核心和容器的一般更新
springframework5改进了组件的扫描和识别方式,从而提高了大型项目的性能。扫描现在发生在编译时,候选组件被添加到META-INF/spring.components
文件中的索引文件中。索引由为项目定义的特定于平台的应用程序生成任务生成。
用javax包中的注释标记的组件与用@index注释的任何类或接口一起添加到索引中。Spring的传统类路径扫描并没有被移除,但仍然是一个回退选项。大型代码库有明显的性能优势,而托管许多Spring项目的服务器将减少启动时间。
spring5还增加了对@Nullable
的支持,它可以用来指示可选的注入点。使用者现在必须准备好接受空值。此外,此注释可用于标记可为null的参数、字段和返回值。@Nullable
主要用于IntelliJ IDEA等ide,但也用于Eclipse和FindBugs,它有助于在编译时处理空值,而不是在运行时发送NullPointerExceptions
。
SpringLogging也得到了提升,它自己的Commons Logging bridge就是现成的。防御编程现在得到了资源抽象的支持,为getFile
访问提供了isFile指示符。
结论
Spring5的主要特性是新的反应式编程模型,它代表了提供无缝伸缩的基于Spring的响应式服务的巨大承诺。随着Spring5的采用,开发人员可以期望看到反应式编程进一步成为Java中web和企业应用程序开发的前进之路。
未来的Spring框架版本将继续反映这一承诺,因为Spring安全性、Spring数据和Spring集成将采用反应式编程的特性和优势。
总而言之,Spring5代表了基于Spring的开发人员一个受欢迎的范式转变,并为其他框架指明了方向。
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/1992.html
暂无评论