2. Features
• Spring 5 is liberated from that legacy baggage. Its codebase has been revamped to take advantage of Java 8 features, and
the framework requires Java 8 as a minimum JDK version
• At the API level, Spring 5 is compatible with Java EE 8 technologies and meets the requirements for Servlet 4.0, Bean
Validation 2.0, and the brand-new JSON Binding API. The minimum requirement for Java EE APIs is version 7, which
introduced minor version releases for the Servlet, JPA, and Bean Validation APIs.
3. Features
• Upgrade to Java SE 8 and Java EE 7
• Reactive programming model
• Programming with annotations
• Functional programming
• Reactive-style programming with REST endpoints
• HTTP/2 support
• Kotlin and Spring WebFlux
• Lambdas for bean registration
• Spring WebMVC support for latest APIs
• Conditional and concurrent testing with JUnit 5
• Integration testing with Spring WebFlux
• Package cleansing and deprecation
• General updates to the Spring core and container
Editor's Notes
What's new in Spring Framework 5
How Spring 5 leverages Java 8’s functional syntax and a new, reactive programming model
Released for general availability (GA) in September 2017, Spring 5 marks the first major Spring Framework release since December 2013. It delivers long-awaited improvements and adopts a new programing paradigm based on reactive principles set out in the reactive manifesto.
This release is by far the most exciting release of the Spring Framework for a long while. Compatible with Java™ 8 and JDK 9, Spring 5 integrates reactive streams for a game-changing approach to endpoint and web application development.
Indeed, reactive programming is the theme for this release, and is the headline feature that has many developers fired up. It fits neatly into the growing requirement for resilient and responsive services that scale seamlessly for a fluctuating load.
This article presents a 30,000-foot view of Spring 5. I introduce baseline upgrades to Java SE 8 and Java EE 7 APIs, Spring 5’s new reactive programming model, HTTP/2 support, and Spring’s full support for functional programming with Kotlin. I also touch briefly on testing and performance enhancements, and conclude with general revisions to the Spring core and container.
Upgrade to Java SE 8 and Java EE 7
Until now, the Spring Framework has supported deprecated Java releases, but Spring 5 is liberated from that legacy baggage. Its codebase has been revamped to take advantage of Java 8 features, and the framework requires Java 8 as a minimum JDK version.
Spring 5 is fully compatible with Java 9 on the classpath, as well as the module path, and it passes the JDK 9 test suite. This is welcome news for Java 9 fans, as Spring will be ready to run with Java 9 as soon as it's released.
At the API level, Spring 5 is compatible with Java EE 8 technologies and meets the requirements for Servlet 4.0, Bean Validation 2.0, and the brand-new JSON Binding API. The minimum requirement for Java EE APIs is version 7, which introduced minor version releases for the Servlet, JPA, and Bean Validation APIs.
Reactive programming model
Spring 5’s most exciting new feature is its reactive programming model. The Spring 5 framework is built on a reactive foundation and is fully asynchronous and nonblocking. The new event-loop execution model can scale vertically with only a small number of threads.
The framework adopts reactive streams to provide a mechanism for communicating backpressure in a pipeline of reactive components. Backpressure is a concept that ensures consumers do not get overwhelmed with data coming from multiple producers.
Spring WebFlux, Spring 5’s reactive core, offers developers two programming models designed for Spring web programming: an annotation-based model and the Functional Web Framework (WebFlux.fn).
The annotation-based model is the modern alternative to Spring WebMVC and is built on reactive foundations, while the Functional Web Framework is the alternative to the @Controller annotation-based programming model. The models run over the same reactive base, which adapts non-blocking HTTP to the reactive streams API.
Programming with annotations
Spring 5’s annotation-based programming model should feel very familiar to WebMVC programmers. Spring 5 has adapted WebMVC’s @Controller programming model and employs the same annotations.
In Listing 1 the BookController class presents two method that respond to HTTP requests for a list of books and a book with the given id. Note the objects returned by the resource methods, Mono and Flux. These are reactive types that implement the Publisher interface from the reactive streamsspecification. Their role is to deal with streams of data. The Mono object deals with a stream of one element, while Flux represents a stream of N elements.
Listing 1. Reactive controller
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
}
That’s annotations for Spring web programming. Now let’s solve the same problem using the functional web framework.
Functional programming
Spring 5’s new functional approach delegates requests to handler functions, which accept a server request instance and return a reactive type. This is demonstrated in Listing 2, where the listBook and getBook methods echo the functionality from Listing 1.
Listing 2. Listing 2. BookHandler function class
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
}
Client requests are routed to the handler via routing functions that match HTTP request predicates and media types. Listing 3 shows the book resource endpoint URI delegating calls to the appropriate handler function:
Listing 3. Router functions
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);
The data repository behind these examples also supports the full reactive experience via Spring Data’s support for reactive Couchbase, Reactive MongoDB, and Cassandra.
Reactive-style programming with REST endpoints
The new programming model is a departure from the traditional Spring WebMVC model and brings with it some very nice new features.
For one, the WebFlux module offers a fully non-blocking and reactive alternative to the RestTemplate, called WebClient. Listing 4 creates a WebClient and calls the books endpoint to request a book with the given id of 1234.
Listing 4. Call REST endpoint with WebClient
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 support
HTTP/2 under the hood: Find out how HTTP/2 improves transport performance, lessens latency, and facilitates greater application throughput for an improved rich web experience in my article on this long-anticipated upgrade.
Spring Framework 5.0 will ship with dedicated HTTP/2 featuressupport, as well as support for the new HTTP client expected in JDK 9. While HTTP/2’s server push feature has been available to Spring developers for quite some time through Jetty servlet engine’s ServerPushFilter class, Web optimizers will be jumping with joy to find HTTP/2 performance enhancements available out of the box in Spring 5.
The Java EE Servlet specification is expected for release in the last quarter of 2017, and Servlet 4.0 support goes live in Spring 5.1. Until then, HTTP/2 features will be provided natively by Tomcat 9.0, Jetty 9.3, and Undertow 1.4.
Kotlin and Spring WebFlux
Kotlin is an object-oriented language from JetBrains that supports functional programming. One of its principal strengths is that it provides very good interoperability with Java. Spring embraces this wholeheartedly in version 5, by introducing dedicated support for Kotlin. Its functional programming style is the ideal match for the Spring WebFlux module, and its new routing DSL leverages the functional web framework with clean and idiomatic code. Endpoint routing can be expressed as simply as shown in Listing 5:
Listing 5. Kotlin’s routing DSL used to define endpoints
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)
}
}
}
Support for Kotlin’s immutable classes with optional parameters with default values and full null-safe APIs has been added, when using Kotlin 1.1.4+.
Lambdas for bean registration
It’s now possible to register a Spring bean using lambdas as an alternative to traditional XML and JavaConfig, so that beans are effectively registered as suppliers. Listing 6 registers a Book bean using lambdas.
Listing 6. Bean registered as a supplier
1
2
3
4
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Book.class, () -> new
Book(context.getBean(Author.class))
);
Spring WebMVC support for latest APIs
The shiny new WebFlux module offers many new and exciting capabilities, but Spring 5 also caters to developers who prefer to continue using Spring MVC. The model-view-controller framework in Spring 5 has been updated to work with WebFlux and the latest versions of Jackson 2.9 and Protobuf 3.0, and even includes support for the new Java EE 8 JSON-Binding API.
In addition to the underlying server implementation of HTTP/2 features, Spring WebMVC also supports Servlet 4.0’s PushBuilder via an argument to the MVC controller methods. Finally, WebMVC includes full support for the Reactor 3.1 Flux and Mono objects, as well as RxJava 1.3 and 2.1, which are treated as return values from MVC controller methods. This support targets the new reactive