Spring Boot Hello World
We will start with building our first Spring Boot application in this lesson. We will use Maven to manage dependencies.
The following steps are involved in starting up with a Spring Boot application:
- Configure
spring-boot-starter-parent
in yourpom.xml
file. - Configure the
pom.xml
file with the required starter projects. - Configure
spring-boot-maven-plugin
to be able to run the application. - Create your first Spring Boot launch class.
Let's start with step 1, configuring the starter projects.
Configure spring-boot-starter-parent
Let's start with a simple pom.xml
file with spring-boot-starter-parent
:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mastering.spring</groupId> <artifactId>springboot-example</artifactId> <version>0.0.1-SNAPSHOT</version> <name>First Spring Boot Example</name> <packaging>war</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.M1</version> </parent> <properties> <java.version>1.8</java.version> </properties> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
The first question is this: why do we need spring-boot-starter-parent
?
A spring-boot-starter-parent
dependency contains the default versions of Java to use, the default versions of dependencies that Spring Boot uses, and the default configuration of the Maven plugins.
Let's look at some of the code inside spring-boot-starter-parent
to get a deeper understanding about spring-boot-starter-parent
.
spring-boot-starter-parent
The spring-boot-starter-parent
dependency inherits from spring-boot-dependencies
, which is defined at the top of the POM. The following code snippet shows an extract from spring-boot-starter-parent
:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.0.0.M1</version> <relativePath>../../spring-boot-dependencies</relativePath> </parent>
The spring-boot-dependencies
provides default dependency management for all the dependencies that Spring Boot uses. The following code shows the different versions of various dependencies that are configured in spring-boot-dependencies
:
<activemq.version>5.13.4</activemq.version> <aspectj.version>1.8.9</aspectj.version> <ehcache.version>2.10.2.2.21</ehcache.version> <elasticsearch.version>2.3.4</elasticsearch.version> <gson.version>2.7</gson.version> <h2.version>1.4.192</h2.version> <hazelcast.version>3.6.4</hazelcast.version> <hibernate.version>5.0.9.Final</hibernate.version> <hibernate-validator.version>5.2.4.Final</hibernate validator.version> <hsqldb.version>2.3.3</hsqldb.version> <htmlunit.version>2.21</htmlunit.version> <jackson.version>2.8.1</jackson.version> <jersey.version>2.23.1</jersey.version> <jetty.version>9.3.11.v20160721</jetty.version> <junit.version>4.12</junit.version> <mockito.version>1.10.19</mockito.version> <selenium.version>2.53.1</selenium.version> <servlet-api.version>3.1.0</servlet-api.version> <spring.version>4.3.2.RELEASE</spring.version> <spring-amqp.version>1.6.1.RELEASE</spring-amqp.version> <spring-batch.version>3.0.7.RELEASE</spring-batch.version> <spring-data-releasetrain.version>Hopper-SR2</spring- data-releasetrain.version> <spring-hateoas.version>0.20.0.RELEASE</spring-hateoas.version> <spring-restdocs.version>1.1.1.RELEASE</spring-restdocs.version> <spring-security.version>4.1.1.RELEASE</spring-security.version> <spring-session.version>1.2.1.RELEASE</spring-session.version> <spring-ws.version>2.3.0.RELEASE</spring-ws.version> <thymeleaf.version>2.1.5.RELEASE</thymeleaf.version> <tomcat.version>8.5.4</tomcat.version> <xml-apis.version>1.4.01</xml-apis.version>
If we want to override a specific version of a dependency, we can do that by providing a property with the right name in the pom.xml
file of our application. The following code snippet shows an example of configuring our application to use version 1.10.20 of Mockito:
<properties> <mockito.version>1.10.20</mockito.version> </properties>
The following are some of the other things defined in spring-boot-starter-parent
:
- The default Java version
<java.version>1.8</java.version>
- The default configuration for Maven plugins:
maven-failsafe-plugin
maven-surefire-plugin
git-commit-id-plugin
Compatibility between different versions of frameworks is one of the major problems faced by developers. How do I find the latest Spring Session version that is compatible with a specific version of Spring? The usual answer would be to read the documentation. However, if we use Spring Boot, this is made simple by spring-boot-starter-parent
. If we want to upgrade to a newer Spring version, all that we need to do is to find the spring-boot-starter-parent
dependency for that Spring version. Once we upgrade our application to use that specific version of spring-boot-starter-parent
, we would have all the other dependencies upgraded to the versions compatible with the new Spring version. One less problem for developers to handle. Always make me happy.
Configure pom.xml with the Required Starter Projects
Whenever we want to build an application in Spring Boot, we would need to start looking for starter projects. Let's focus on understanding what a starter project is.
Starters are simplified dependency descriptors customized for different purposes. For example, spring-boot-starter-web
is the starter for building web application, including RESTful, using Spring MVC. It uses Tomcat as the default embedded container. If I want to develop a web application using Spring MVC, all we would need to do is include spring-boot-starter-web
in our dependencies, and we get the following automatically pre-configured:
- Spring MVC
- Compatible versions of
jackson-databind
(for binding) and hibernate-validator (for form validation) spring-boot-starter-tomcat
(starter project for Tomcat)
The following code snippet shows some of the dependencies configured in spring-boot-starter-web
:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> </dependencies>
As we can see in the preceding snippet, when we usespring-boot-starter-web
, we get a lot of frameworks auto-configured.
For the web application we would like to build, we would also want to do some good unit testing and deploy it on Tomcat. The following snippet shows the different starter dependencies that we would need. We would need to add this to our pom.xml
file:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> </dependencies>
We add three starter projects:
- We've already discussed
spring-boot-starter-web
. It provides us with the frameworks needed to build a web application with Spring MVC. - The
spring-boot-starter-test
dependency provides the following test frameworks needed for unit testing:- JUnit: Basic unit test framework
- Mockito: For mocking
- Hamcrest, AssertJ: For readable asserts
- Spring Test: A unit testing framework for spring-context based applications
- The
spring-boot-starter-tomcat
dependency is the default for running web applications. We include it for clarity. Thespring-boot-starter-tomcat
is the starter for using Tomcat as the embedded servlet container.
We now have our pom.xml
file configured with the starter parent and the required starter projects. Let's add spring-boot-maven-plugin
now, which would enable us to run Spring Boot applications.
Configuring spring-boot-maven-plugin
When we build applications using Spring Boot, there are a couple of situations that are possible:
- We would want to run the applications in place without building a JAR or a WAR
- We would want to build a JAR and a WAR for later deployment
The spring-boot-maven-plugin
dependency provides capabilities for both of the preceding situations. The following snippet shows how we can configure spring-boot-maven-plugin
in an application:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
The spring-boot-maven-plugin
dependency provides several goals for a Spring Boot application. The most popular goal is run (this can be executed as mvn spring-boot:run
on the command prompt from the root folder of the project).
Creating Your First Spring Boot Launch Class
The following class explains how to create a simple Spring Boot launch class. It uses the static run method from the SpringApplication
class, as shown in the following code snippet:
package com.mastering.spring.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class Application { public static void main(String[] args) { ApplicationContext ctx = SpringApplication.run (Application.class,args); } }
The preceding code is a simple Java main
method executing the static run
method on the SpringApplication
class.
The SpringApplication
class can be used to Bootstrap and launch a Spring application from a Java main
method.
The following are the steps that are typically performed when a Spring Boot application is bootstrapped:
- Create an instance of Spring's
ApplicationContext
. - Enable the functionality to accept command-line arguments and expose them as Spring properties.
- Load all the Spring beans as per the configuration.
The @SpringBootApplication
annotation is a shortcut for three annotations:
@Configuration
: Indicates that this a Spring application context configuration file.@EnableAutoConfiguration
: Enables auto-configuration, an important feature of Spring Boot. We will discuss auto-configuration later in a separate section.@ComponentScan
: Enables scanning for Spring beans in the package of this class and all its sub packages.
Running Our Hello World Application
We can run the Hello World application in multiple ways. Let's start running it with the simplest option--running as a Java application. In your IDE, right-click on the application class and run it as Java Application. The following screenshot shows some of the log from running our Hello World
application:
The following are the key things to note:
- Tomcat server is launched on port
8080
--Tomcat started on port(s): 8080 (http)
. DispatcherServlet
is configured. This means that Spring MVC Framework is ready to accept requests--Mapping servlet: 'dispatcherServlet' to [/]
.- Four filters--
characterEncodingFilter
,hiddenHttpMethodFilter
,httpPutFormContentFilter
andrequestContextFilter
--are enabled by default - The default error page is configured--
Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
- WebJars are autoconfigured. WebJars enable dependency management for static dependencies such as Bootstrap and query--
Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
The following screenshot shows the application layout as of now. We have just two files, pom.xml
and Application.java
:
With a simple pom.xml
file and one Java class, we were able to get to launch the Spring MVC application, with all the preceding functionality described. The most important thing about Spring Boot is to understand what happens in the background. Understanding the preceding start up log is the first. Let's look at the Maven dependencies to get a deeper picture.
The following screenshot shows some of the dependencies that are configured with the basic configuration in the pom.xml
file that we created:
Spring Boot does a lot of magic. Once you have the application configured and running, I recommend that you play around with it to gain a deeper understanding that will be useful when you are debugging problems.
As Spiderman says, with great power, comes great responsibility. This is absolutely true in the case of Spring Boot. In the time to come, the best developers with Spring Boot would be the ones who understand what happens in the background--dependencies and auto-configuration.
Auto-configuration
To enable us to understand auto-configuration further, let's expand our application class to include a few more lines of code:
ApplicationContext ctx = SpringApplication.run(Application.class, args); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); }
We get all the beans that are defined in the Spring application context and print their names. When Application.java
is run as a Java program, it prints the list of beans, as shown in the following output:
application basicErrorController beanNameHandlerMapping beanNameViewResolver characterEncodingFilter conventionErrorViewResolver defaultServletHandlerMapping defaultViewResolver dispatcherServlet dispatcherServletRegistration duplicateServerPropertiesDetector embeddedServletContainerCustomizerBeanPostProcessor error errorAttributes errorPageCustomizer errorPageRegistrarBeanPostProcessor faviconHandlerMapping faviconRequestHandler handlerExceptionResolver hiddenHttpMethodFilter httpPutFormContentFilter httpRequestHandlerAdapter jacksonObjectMapper jacksonObjectMapperBuilder jsonComponentModule localeCharsetMappingsCustomizer mappingJackson2HttpMessageConverter mbeanExporter mbeanServer messageConverters multipartConfigElement multipartResolver mvcContentNegotiationManager mvcConversionService mvcPathMatcher mvcResourceUrlProvider mvcUriComponentsContributor mvcUrlPathHelper mvcValidator mvcViewResolver objectNamingStrategy autoconfigure.AutoConfigurationPackages autoconfigure.PropertyPlaceholderAutoConfiguration autoconfigure.condition.BeanTypeRegistry autoconfigure.context.ConfigurationPropertiesAutoConfiguration autoconfigure.info.ProjectInfoAutoConfiguration autoconfigure.internalCachingMetadataReaderFactory autoconfigure.jackson.JacksonAutoConfiguration autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration autoconfigure.jmx.JmxAutoConfiguration autoconfigure.web.DispatcherServletAutoConfiguration autoconfigure.web.DispatcherServletAutoConfiguration$DispatcherServletConfiguration autoconfigure.web.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration autoconfigure.web.EmbeddedServletContainerAutoConfiguration autoconfigure.web.EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat autoconfigure.web.ErrorMvcAutoConfiguration autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration autoconfigure.web.HttpEncodingAutoConfiguration autoconfigure.web.HttpMessageConvertersAutoConfiguration autoconfigure.web.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration autoconfigure.web.JacksonHttpMessageConvertersConfiguration autoconfigure.web.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfiguration autoconfigure.web.MultipartAutoConfiguration autoconfigure.web.ServerPropertiesAutoConfiguration autoconfigure.web.WebClientAutoConfiguration autoconfigure.web.WebClientAutoConfiguration$RestTemplateConfiguration autoconfigure.web.WebMvcAutoConfiguration autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter$FaviconConfiguration autoconfigure.websocket.WebSocketAutoConfiguration autoconfigure.websocket.WebSocketAutoConfiguration$TomcatWebSocketConfiguration context.properties.ConfigurationPropertiesBindingPostProcessor context.properties.ConfigurationPropertiesBindingPostProcessor.store annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor annotation.ConfigurationClassPostProcessor.importAwareProcessor annotation.internalAutowiredAnnotationProcessor annotation.internalCommonAnnotationProcessor annotation.internalConfigurationAnnotationProcessor annotation.internalRequiredAnnotationProcessor event.internalEventListenerFactory event.internalEventListenerProcessor preserveErrorControllerTargetClassPostProcessor propertySourcesPlaceholderConfigurer requestContextFilter requestMappingHandlerAdapter requestMappingHandlerMapping resourceHandlerMapping restTemplateBuilder serverProperties simpleControllerHandlerAdapter spring.http.encoding-autoconfigure.web.HttpEncodingProperties spring.http.multipart-autoconfigure.web.MultipartProperties spring.info-autoconfigure.info.ProjectInfoProperties spring.jackson-autoconfigure.jackson.JacksonProperties spring.mvc-autoconfigure.web.WebMvcProperties spring.resources-autoconfigure.web.ResourceProperties standardJacksonObjectMapperBuilderCustomizer stringHttpMessageConverter tomcatEmbeddedServletContainerFactory viewControllerHandlerMapping viewResolver websocketContainerCustomizer
Important things to think about are as follows:
- Where are these beans defined?
- How are these beans created?
That's the magic of Spring auto-configuration.
Whenever we add a new dependency to a Spring Boot project, Spring Boot auto-configuration automatically tries to configure the beans based on the dependency.
For example, when we add a dependency in spring-boot-starter-web
, the following beans are auto-configured:
basicErrorController
,handlerExceptionResolver
: It is the basic exception handling. It shows a default error page when an exception occurs.beanNameHandlerMapping
: It is used to resolve paths to a handler (controller).characterEncodingFilter
: It provides default character encoding UTF-8.dispatcherServlet
: It is the front controller in Spring MVC applications.jacksonObjectMapper
: It translates objects to JSON and JSON to objects in REST services.messageConverters
: It is the default message converters to convert from objects into XML or JSON and vice versa.multipartResolver
: It provides support to upload files in web applications.mvcValidator
: It supports validation of HTTP requests.viewResolver
: It resolves a logical view name to a physical view.propertySourcesPlaceholderConfigurer
: It supports the externalization of application configuration.requestContextFilter
: It defaults the filter for requests.restTemplateBuilder
: It is used to make calls to REST services.tomcatEmbeddedServletContainerFactory
: Tomcat is the default embedded servlet container for Spring Boot-based web applications.
In the next section, let's look at some of the starter projects and the auto-configuration they provide.
Starter Projects
The following table shows some of the important starter projects provided by Spring Boot:
Until now, we have set up a basic web application and understood some of the important concepts related to Spring Boot:
- Auto-configuration
- Starter projects
spring-boot-maven-plugin
spring-boot-starter-parent
- Annotation
@SpringBootApplication
Now let's shift our focus to understanding what REST is and building a REST Service.