days
1
5
hours
1
9
minutes
3
5
seconds
4
6
search
The boots tightly laced twice

Spring Boot 2 – An introduction: Current dependencies & the basis Spring 5

Michael Simons
© Shutterstock.com / GraphicsRF

New topics, new functions but also some work in your luggage: With Spring Boot 2, Pivotal’s developers are launching a new generation of convention pre-configuration solution for building Spring applications. In this series of articles Michael Simons, Senior Consultant at innoQ Germany, gives a comprehensive introduction to the basics and the news of the new version of Spring Boot.

Michael Simons is not only speaker at JAX 2018, but also author of the book “Spring Boot – Moderne Softwareentwicklung im Spring Ökosystem”, published by dpunkt.verlag.

Spring Boot 2: Many updated dependencies

Over the past three years Spring Boot has brought a breath of fresh air into the world of Spring and Java EE (now Jakarta EE – editor’s note). The project is not a new framework, but a comprehensive solution that simplifies dependency management and Build, and much more. It can be confidently postulated that new Spring projects should generally be implemented with Spring Boot – regardless of whether microservices or monoliths are created.

The fifth generation of the Spring Framework was released at the end of September 2017 and Spring Boot 2 was released on March 1st 2018. Upgrades of the central dependencies, especially the Spring Framework and Spring Security, as well as larger refactoring and cleanup work bring new topics, new functions but also a lot of work. This series of articles sheds light on some of them.

Version updates

Spring 5 and Spring Boot 2 require Java 8, making it possible to use core Java 8 functions. This includes default-Methods on interfaces and the associated deprecation of several AbstractXXXConfigurer-classes, Nullable-Support and more.

All Java EE specifications that are also used in Spring have been upgraded to Java EE 7. While Spring Boot 1 is the last Spring Boot version that supports Java 7, Spring Boot 2 will be the first version that runs on Java 9 (and is expected to run on Java 10). This is accompanied by several upgrades of fundamental dependencies: for example to Tomcat, Hibernate and Gradle. For the complete list, check the Spring Boot Bill of Materials (BOM).

HTTP/2-Support

A highlight of Spring Boot 2 is the almost automatically available HTTP/2 support: The used versions of Tomcat, Jetty, Undertow and Reactor Netty support HTTP/2 out-of-the-box. The configuration is very simple: The server certificate must be configured with properties underserver.ssl.* , then HTTP/2 can be activated viaserver.http2.enabled. HTTP/2 is an important building block for a faster web.  Latencies can be drastically reduced by compressing headers, server push, requesting pipelines, and multiplexing requests.

Actual versions of Spring projects

The dependencies that Spring Boot manages also includes other Spring projects, namely Spring itself, but also Spring Data and Spring Security. Unlike the Spring Cloud Stack, these are part of the Spring Boot BoM and an update to Spring Boot 2 upgrades them as well. While the update to Spring Boot is in most cases rather unproblematic, changes in the upstream projects often turn out to be critical. So before we go into specific topics of Spring Boot 2, in this first part I will introduce the new foundation, the Spring Framework 5 and its highlights.

SEE ALSO: Spring Boot – what it is and how to get started

Spring 5: The basis of Spring Boot 2 and its modules

The fifth generation of the Spring Framework was released at the end of September 2017. Spring 5 is the basis for most of the frameworks curated in Spring Boot and creates the basis for the topic “reactive programming”.

Reactive programming with Spring 5

A dominant topic of Spring 5 is the reactive programming model. Reactive programming is not a new topic and not a unique feature of Spring 5 and Spring Boot 2. The Java 9 Flow API and implementations like Project Reactor and ReactiveX provide basic technologies, while frameworks like Vert.x fully follow the reactive programming model.

Spring 5 takes a different approach and provides the reactive programming model parallel to the existing approach. There are non-blocking alternatives, from the frequent entry point, the web front-end and security to data storage. This provides a way that can also be mastered in organizations that do not want to move too far away from a known stack.

The core topic of reactive programming is not faster applications, but more robust and resource-saving components of systems – an elementary aim in times in which applications are often only small components within a large system. The Reactive manifest defines reactive applications as “elastic, robust, always ready to respond and message-oriented”.

These targets are achieved among other things by the fact that Spring’s reactive infrastructure no longer exclusively blocks threads. Long-lasting, sometimes slow connections, no longer occupy resources permanently. Memory consumption can be reduced by data processing based on data streams. Results are not processed in one piece, but in elements.

Mono and Flux

In some of the following examples the classes Mono and Flux are used. They are both implementations of a Flow API publisher and represent sequences of things that happen or are published along a timeline.
In this way, processing is asynchronous and ends when a publisher no longer offers any further elements. Operators create new publishers. A mono publishes 0 or 1, a flux n elements. Figure 1 shows the representation of a flux. Diagrams of this type are also known as a marble diagram.

Fig. 1: Timeline of a flux

Spring WebFlux

First of all, it should be made clear once again that the new Spring WebFlux module is only the “face” of reactive programming with Spring. Reactive runs through several Spring modules up to Spring Core. Spring WebFlux is available as an alternative to the classic Spring Web MVC, as shown in Figure 2.

Figure 2: Spring WebFlux as an alternative to Spring Web MVC

Of course there is a corresponding starter available for WebFlux with org.springframework.boot:spring-boot-starter-webflux, which among other things automatically defines @EnableWebFlux. The transitive dependencies of the starter are required, independent of whether the classical or functional programming model for WebFlux is used.

Traditional

The fact that the classic Spring Web MVC annotations @Controller and @RequestMapping are also available for WebFlux is clearly visible. This makes it easier to get started and a reactive jump controller could look like in Listing 1:

@RestController
public class DemoRestController {
    @GetMapping("/helloworld")
    public Mono<string> getGreeting(
        @RequestParam(defaultValue = "World") String name
    ) {
        return Mono.just("Hello")
            .flatMap(s -> Mono
                .just(s + ", " + name + "!\n")
            );
    }
}
</string>

An asynchronous, non-blocking “Hello, World”. The Spring-infrastructure and also the automatic configuration in Spring Boot have been redesigned. HandlerMapping and HandlerAdapter now use either the classic mechanisms HttpServletRequest and HttpServletResponse or the reactive ServerHttpRequest and ServerHttpResponse. WebFlux runs on all Servlet 3.1 containers that support the Non-Blocking IO API, but also on other asynchronous runtime environments such as Netty and Undertow. The basic technology for stream processing is Project-Reactor. Alternatively, you can also use and configure RxJava.

In a Spring-Boot-2 application that uses the starter spring-boot-starter-webflux, Listing 1’s controller works out of the box. Spring Boot will then use Netty by default. Spring 5 can still be used without Spring Boot, the appropriate server must then be registered programmatically.

Functional

Annotations are not universally loved. Spring 5 and the reactive programming model also cover this topic and provide another way to configure a jump context. Listing 2 shows an alternative way to define handlers and routes completely without annotations.

public class DemoFunctionalProgrammingModel {
    public static void main(String...a) {
 
        HandlerFunction helloWorld =
            request -> ServerResponse.ok().body(
                Mono.just("Hello, World"), String.class
            );
 
 
        RouterFunction helloSpringRoute =
            request ->  {
                if(request.method() == GET &&
                    request.path().equals("/hellospring")
                ) {
                    return Mono.just(r ->
                        ok().body(
                            Mono.just("Functional Spring"),
                            String.class
                        )
                    );
                } else {
                    return Mono.empty();
                }
            };
 
        RouterFunction helloWorldRoute =
            RouterFunctions.route(
                GET("/helloworld"), helloWorld);
 
        RouterFunction routes = helloSpringRoute
            .and(helloWorldRoute);
 
        HttpHandler httpHandler = RouterFunctions
            .toHttpHandler(routes);
        HttpServer.create(8080)
            .newHandler(new ReactorHttpHandlerAdapter(httpHandler))
            .block();
 
        CountDownLatch latch = new CountDownLatch(1);
        Thread awaitThread = new Thread(() -> {
            try {
                latch.await();
            } catch (InterruptedException ex) {
            }
 
        });
        awaitThread.setDaemon(false);
        awaitThread.start();
    }
}

While the functional routing of requests is only available for Spring WebFlux, the functional bean registration can be used in the entire context. From the class genericApplicationContext comes RegisterBean. Now the method accepts Java 8 Supplier: context.registerBean(MyService.class, MyService::new);

Reactive Clients, Tests

In the quick run above, the new WebClient, which will supersede the AsyncRestTemplate in the medium term, was embezzled. The <code<RestTemplate itself remains unchanged. The new infrastructure is fully testable as an @WebFluxTest slice.

Only WebFlux?

The Spring MVC Framework, based on the servlet specification, will continue to have first-class support; existing applications do not have to be rewritten to WebFlux for no reason. Currently, applications that use blocking APIs such as JPA or JDBC do not benefit from WebFlux. Applications with non-blocking protocols and drivers consistently provided for their stack will get a completely non-blocking stack.

SEE ALSO: Micrometer: a dimensional-first metrics collector for Spring Boot 2

Kotlin-Extensions

Really interesting are router functions, functional bean registration and other little things in combination with Spring’s new, official support for Kotlin. Listing 3 shows impressively that a Spring boot application no longer has to look like Spring and can completely do without annotations and XML. In the class Handler the application is manifested, the class Router represents URLs on the functions of the handler and uses the special DSL router. Similar information is provided for bean registration with beans.

class Handler {
    fun sayHello(req: ServerRequest) =
            ok().body(
                    Mono.just("Hello, ${req.queryParam("name").orElse("World")}"),
                    String::class.java
            )
 
    fun andGoodbye(req: ServerRequest) =
            ok().body(
                    Mono.just("Goodbye"),
                    String::class.java
            )
}
 
class Router(val handler: Handler) {
    fun routes() = router {
        ("/greetings" and accept(TEXT_HTML)).nest {
            GET("/hello", handler::sayHello)
            GET("/goodbye", handler::andGoodbye)
        }
    }
}
 
fun beans() = beans {
    bean()
    bean {
        Router(ref()).routes()
    }
}
 
@SpringBootApplication
class Application
 
fun main(args: Array) {
    runApplication(*args)
}

Of course, the same applies here as well as to Spring and other applications: framework specific annotations and classes have rarely lost anything in domain-oriented classes. The controllers in these examples process data directly; in any realistic application, application and service layers should still be separated.

In the next part, I will discuss the changes in the Spring Data and Spring Security projects. These will certainly affect your applications when you upgrade from Spring Boot 1 to Spring Boot 2 and may require active migration.

Spring Boot – Modern software development within the Spring ecosystem

The Spring Boot book will be published in late April 2018 and will cover all current topics related to Spring Boot 2. In addition to the reactive programming model with Spring 5, this includes the new actuator infrastructure, Micrometer.io support and much more.

This book is intended to appeal to interested developers from the Java EE area as well as Spring developers and give them a “recipe” to handle recurring tasks from everyday business life elegantly and without distraction using Spring Boot.

Author
spring boot

Michael Simons

Michael Simons works as a Senior Consultant at innoQ Germany. He is a member of the NetBeans Dream Team and founder of the Euregio JUG. Michael writes on his blog about Java, Spring and software architecture. He is on Twitter as @rotnroll666, where he deals with Java, music and minor and major problems as a husband and father of two children. In January 2018 Michael’s book “Spring Boot — Moderne Softwareentwicklung im Spring-Ökosystem” will be published by dpunkt.verlag. The book can already be pre-ordered at springbootbuch.de. It covers Spring Boot 2 and the new, reactive programming paradigm of Spring 5 as well as Spring basics and thus appeals to experienced Spring developers as well as new beginners. The diagrams in this article are also from the book, as are some of the examples shown. The code is already available on GitHub.


Leave a Reply

Be the First to Comment!

avatar
400
  Subscribe  
Notify of