4年前 (2021-06-07)  Java系列 |   抢沙发  530 
文章评分 0 次,平均分 0.0

spring5新特性一览

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中演示了这一点,其中listBookgetBook方法与清单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.accessjdbc.support.nativejdbcmock.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

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册