Book Image

Spring Boot 2.0 Cookbook - Second Edition

By : Alex Antonov
Book Image

Spring Boot 2.0 Cookbook - Second Edition

By: Alex Antonov

Overview of this book

The Spring framework provides great flexibility for Java development, which also results in tedious configuration work. Spring Boot addresses the configuration difficulties of Spring and makes it easy to create standalone, production-grade Spring-based applications. This practical guide makes the existing development process more efficient. Spring Boot Cookbook 2.0 Second Edition smartly combines all the skills and expertise to efficiently develop, test, deploy, and monitor applications using Spring Boot on premise and in the cloud. We start with an overview of the important Spring Boot features you will learn to create a web application for a RESTful service. Learn to fine-tune the behavior of a web application by learning about custom routes and asset paths and how to modify routing patterns. Address the requirements of a complex enterprise application and cover the creation of custom Spring Boot starters. This book also includes examples of the new and improved facilities available to create various kinds of tests introduced in Spring Boot 1.4 and 2.0, and gain insights into Spring Boot DevTools. Explore the basics of Spring Boot Cloud modules and various Cloud starters to make applications in “Cloud Native” and take advantage of Service Discovery and Circuit Breakers.
Table of Contents (11 chapters)

Creating a simple application

Now that we have a basic idea of the starters that are available to us, let's go ahead and create our application template at http://start.spring.io.

How to do it...

The application that we are going to create is a book catalog management system. It will keep a record of books that were published, who the authors were, the reviewers, publishing houses, and so forth. We will name our project BookPub, and apply the following steps:

  1. First let's switch to the full version by clicking the link below the Generate Project alt + button
  2. Choose Gradle Project at the top
  3. Use Spring Boot version 2.0.0(SNAPSHOT)
  4. Use the default proposed Group name: com.example
  5. Enter bookpub for an Artifact field
  6. Provide BookPub as a Name for the application
  7. Specify com.example.bookpub as our Package Name
  8. Select Jar as Packaging
  9. Use Java Version as 8
  10. Select the H2, JDBC, and JPA starters from the Search for dependencies selection so that we can get the needed artifacts in our build file to connect to an H2 database
  11. Click on Generate Project alt + to download the project archive

How it works...

Clicking on the Generate Project alt + button will download the bookpub.zip archive, which we will extract from our working directory. In the newly created bookpub directory, we will see a build.gradle file that defines our build. It already comes preconfigured with the right version of a Spring Boot plugin and libraries, and even includes the extra starters, which we have chosen. The following is the code of the build.gradle file:

dependencies { 
  compile("org.springframework.boot:spring-boot-starter-data-jpa") 
  compile("org.springframework.boot:spring-boot-starter-jdbc") 
  runtime("com.h2database:h2") 
  testCompile("org.springframework.boot:spring-boot-starter-test")  
} 

We have selected the following starters:

  • org.springframework.boot:spring-boot-starter-data-jpa: This starter pulls in the JPA dependency.
  • org.springframework.boot:spring-boot-starter-jdbc: This starter pulls in the JDBC supporting libraries.
  • com.h2database: H2 is a particular type of database implementation, namely H2.
  • org.springframework.boot:spring-boot-starter-test: This starter pulls all the necessary dependencies for running tests. It is only being used during the test phase of the build, and it is not included during the regular application compile time and runtime.

As you can see, the runtime("com.h2database:h2") dependency is a runtime one. This is because we don't really need, and probably don't even want to know, the exact type of database to which we will connect at the compile time. Spring Boot will autoconfigure the needed settings and create appropriate beans once it detects the presence of the org.h2.Driver class in the classpath when the application is launched. We will look into the inner workings of how and where this happens later in this chapter.

The data-jpa and jdbc are Spring Boot starter artifacts. If we look in these dependency JARs once they are downloaded, or using Maven Central, we will find that they don't contain any actual classes, only the various metadata. The two containing files that are of interest are pom.xml and spring.provides. Let's first look at the spring.provides file in the spring-boot-starter-jdbc JAR artifact, as follows:

provides: spring-jdbc,spring-tx,tomcat-jdbc 

This tells us that, by having this starter as our dependency, we will transitively get the spring-jdbc, spring-tx, and tomcat-jdbc dependency libraries in our build. The pom.xml file contains the proper dependency declarations that will be used by Gradle or Maven to resolve the needed dependencies during the build time. This also applies to our second starter: spring-boot-starter-data-jpa. This starter will transitively provide us with the spring-orm, hibernate-entity-manager, and the spring-data-jpa libraries.

At this point, we have enough libraries/classes in our application classpath so as to give Spring Boot an idea of what kind of application we are trying to run and what type of facilities and frameworks need to be configured automatically by Spring Boot to stitch things together.

Earlier, we mentioned that the presence of the org.h2.Driver class in the classpath will trigger Spring Boot to automatically configure the H2 database connection for our application. To see exactly how this will happen, let's start by looking at our newly created application template, specifically at BookPubApplication.java, which is located in the src/main/java/com/example/bookpub directory in the root of the project. We do this as follows:

    package com.example.bookpub; 
 
    import org.springframework.boot.SpringApplication; 
    import org.springframework.boot.autoconfigure.
SpringBootApplication; @SpringBootApplication public class BookPubApplication { public static void main(String[] args) { SpringApplication.run(BookPubApplication.class, args); } }

This is effectively our entire and fully runnable application. There's not a whole lot of code here and definitely no mention of configuration or databases anywhere. The key to making magic is the @SpringBootApplication meta-annotation. In this, we will find the real annotations that will direct Spring Boot to set things up automatically:

    @SpringBootConfiguration 
    @EnableAutoConfiguration 
    @ComponentScan (excludeFilters = @Filter(type =  
FilterType.CUSTOM, classes = TypeExcludeFilter.class)) public @interface SpringBootApplication {...}

Let's go through the following list of annotations mentioned in the preceding code snippet:

  • @SpringBootConfiguration: This annotation is in itself a meta-annotation; it tells Spring Boot that the annotated class contains Spring Boot configuration definitions, such as the @Bean, @Component, and @Service declarations, and so on. Inside, it uses the @Configuration annotation, which is a Spring annotation, and not just Spring Boot, as it is a Spring Framework core annotation, used to mark classes containing Spring configuration definitions.
It is important to note that using @SpringBootConfiguration over @Configuration is helpful when executing tests with Spring Boot Test framework, as this configuration will automatically be loaded by the Test framework when the test is annotated with @SpringBootTest. As it is noted in the Javadoc, an application should only ever include one @SpringApplicationConfiguration, and most idiomatic Spring Boot applications will inherit it from @SpringBootApplication.
  • @ComponentScan: This annotation tells Spring that we want to scan our application packages starting from the package of our annotated class as a default package root for the other classes that may be annotated with @Configuration, @Controller, and other applicable annotations, which Spring will automatically include as part of the context configuration. The applied TypeExcludeFilter class provides filtering out for various classes to be excluded from ApplicationContext. It is mostly used by spring-boot-test to exclude classes that should be used only during tests; however, it is possible to add your own beans that extend from TypeExcludeFilter and provide filtering for other types that are deemed necessary.
  • @EnableAutoConfiguration: This annotation is a part of the Spring Boot annotation, which is a meta-annotation on its own (you will find that Spring libraries rely very heavily on the meta-annotations so they can group and compose configurations together). It imports the EnableAutoConfigurationImportSelector and AutoConfigurationPackages.Registrar classes that effectively instruct Spring to automatically configure the conditional beans depending on the classes available in the classpath. (We will cover the inner workings of autoconfiguration in detail in Chapter 4, Writing Custom Spring Boot Starters.)

The SpringApplication.run(BookPubApplication.class, args); code line in the main method basically creates a Spring application context that reads the annotations in BookPubApplication.class and instantiates a context, which is similar to how it would have been done had we not used Spring Boot and stuck with just a regular Spring Framework.