Post Thumbnail

Introduction to Spring Boot

1. Overview

Spring Boot is a framework for building web applications using the Java programming language. Web applications are software that can be accessed over the internet via a Web browser.

We can use Spring Boot to create RESTFul APIs, SOAP APIs, Websocket Applications, Front-end applications with HTML/CSS and many more.

It favours convention over configurations. This means a lot of things has been done setup by default and requires little effort from the Engineer to make it work.

This also means that there’s a Spring Boot way of doing things. The Engineer is expected to do some things in a pre-defined way.

This opinionated approach makes it easy to learn the framework and boosts developer’s productivity as it comes with a lot of production-ready logic.

For example, to connect to a database, we only need to add a configuration property called spring.datasource.url that points to the URL of the database. Spring Boot will deal with automatic opening and closing of connection, converting the data from the SQL result into a Java object and so on.

Spring Boot enables us to build cloud-native applications. It supports the use of environment-specific configurations to alter the behaviour of the application.

It can be deployed in a Kubernetes environment via Docker, supports automatic service discovery, contextual logging, health and liveness checks and other actuator functionalities.

At the end of this article, you would have learnt about the basics of Spring Boot and how to create a hello world application with it.

2. How to Create a new Spring Boot Project

Before creating a new project, we must have Java Development Kit (JDK) set up on our local machine. This is because Spring Boot is a Java framework and requires the JDK to run.

One of the simplest ways to create a new Spring Boot project is by generating one on https://start.spring.io/.

On the website, we can select the build tool (Maven or Gradle), the Spring Boot version, specify the project metadata (group, artifact, name, description) and finally, the packaging (Jar or War) we want to use.

Since this is an introductory article, our focus will be on altering the project metadata. We will accept the default for the other fields.

The project metadata is a globally unique identification scheme for the application we want to create. It uses the domain name as the group identifier, since a domain name is already globally unique.

If you own a domain name like smattme.com, you can reverse it and use it as the group identifier - com.smattme.

If you do not have a domain name, you can use your GitHub/Gitlab username. Assuming your GitHub username is SeunMatt, then you can use com.github.seunmatt as the project’s group identifier.

The Artifact is the name for your project. Preferably, in lowercase letters with no white space.

Someone building a digital wallet application can use wallet as the artifact name while someone working on an Admin portal can simply call it adminportal.

The package name is the root package name. By convention, it is a combination of the group and the artifact names. It does not allow for special characters, apart from the underscore (_).

For the purpose of this article, we will use the following values for the project metadata:

  • Group: com.smattme
  • Artifact: spring-boot-intro
  • Name: spring-boot-intro
  • Description: Project for introduction to Spring Boot
  • Package name: com.smattme.springbootintro

We will use the default values for build tool (Maven), language (Java) and packaging (Jar).

Still on the same spring initialzr page, we can add one or more dependencies to the project.

Dependencies are other softwares, functions that our project will require to work. Remember the old saying of do not re-invent the wheel? This is where we apply it.

From the right side of the page, click on the ADD DEPENDENCIES... button. For this introduction, we will only need the Spring Web and Spring Boot Actuator dependencies.

We can add more dependencies, as required, in the future, even after the project has been generated.

Spring Boot Initialzr Page

Lastly, let’s click on the Generate button at the bottom of the page to download the project. This will download a .zip file to our local machine.

Unzip the file and open it in your favourite IDE (IntelliJ, Eclipse, Netbeans, VS Code) or a text editor like Sublime Text.

3. Structure of a Spring Boot Project

The folder structure of a Spring Boot project is the same as that of a typical Maven project:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
./
├── HELP.md
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── smattme
│   │   │           └── springbootintro
│   │   │               └── SpringBootIntroApplication.java
│   │   └── resources
│   │       ├── application.properties
│   │       ├── static
│   │       └── templates
│   └── test
│       └── java
│           └── com
│               └── smattme
│                   └── springbootintro
│                       └── SpringBootIntroApplicationTests.java

The pom.xml file is where we can find the project metadata, dependencies and build plugins.

Perhaps the most important section of the pom.xml to a beginner is the <dependencies> element.

It is where all the libraries that the application requires is declared. The spring web, and actuator dependencies we added earlier are already present in this section.

If we want to add new dependencies, we need to add them to this <dependencies> section.

The src folder contains two main subfolders; namely main and test.

The main folder contains code that will execute when we run the application. It is further organised into two subfolders of itself, namely java and resources.

The java folder contains the top-level package(s).

What is a package? It simply refers to a series of folders, created to help organize the source code for ease of maintenance and collaboration.

Under the hood, a package is a series of folders in a folder. For example, the package com.smattme.springbootintro corresponds to the following folder structure on the computer: src/main/com/smattme/springbootintro.

While there are no hard rules, by convention, there should only be one main package. Other packages should be created under the main package.

The main package contains a Java class named SpringBootIntroApplication which has the main method. This is the entry point for the application as it is the main class.

It is called the main class because it contains the main method.

This main class is annotated with @SpringBootApplication. The presence of this annotation is the definitive way to know this is a Spring Boot application and codebase.

The src/main folder also contain the resources folder. This is where we keep all other non-Java files required for the functioning of the application.

These include property files, HTML, CSS, Javascript and other static resources.

The application.properties file in the resources folder is where we can configure the Spring Boot application. It’s where we can declare properties like spring.application.name and server.port to configure the application name and port respectively.

The static folder is where we keep all static resources like CSS, Javascript, favicons and images required by the web application.

In some codebase, it may be named public. This is usually to conform with the old convention of website deployment where images, Javascript and CSS are kept in the public folder.

The templates directory is where we keep the HTML files and templates. This will be required if we are building a web application that has a UI component.

You can watch this other tutorial to learn how to create a Spring Boot application with HTML/CSS template.

The test source folder mimics the structure of the main source folder. Albeit, the test folder contains only test source code. The Java classes in the test directory will only be available when we are running tests.

Spring Initializr generate a default test class SpringBootIntroApplicationTests that we can run and fine-tune to taste.

At this point, without changing anything, we can start the application, and it will work. This is because Spring Boot comes with sensible defaults and aims to minimise manual configurations except where required.

4. How to start a Spring Boot application

If you are using an IDE like IntelliJ or Eclipse, open the SpringBootIntroApplication. You should see a play icon (▶️) beside the main method. Click on it to run the application.

In VS Code, you can right-click on the SpringBootIntroApplication class file and select the Run Java option to start the application.

If none of the above applies or just for the fun of it, we can run the application via the command line. Navigate to the root of the project and execute the following command:

1
 mvn clean compile spring-boot:run

If the application starts successfully, you’ll see similar logs in the console:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.4)

2024-10-05T18:18:03.956+01:00  INFO 8947 --- [spring-boot-intro] [           main] c.s.s.SpringBootIntroApplication         : Starting SpringBootIntroApplication using Java 21 with PID 8947 (/smattme-tutorials/spring-boot-intro/target/classes started by smatt in /smattme-tutorials/spring-boot-intro)
2024-10-05T18:18:03.957+01:00  INFO 8947 --- [spring-boot-intro] [           main] c.s.s.SpringBootIntroApplication         : No active profile set, falling back to 1 default profile: "default"
2024-10-05T18:18:04.400+01:00  INFO 8947 --- [spring-boot-intro] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-10-05T18:18:04.407+01:00  INFO 8947 --- [spring-boot-intro] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-10-05T18:18:04.407+01:00  INFO 8947 --- [spring-boot-intro] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.30]
2024-10-05T18:18:04.431+01:00  INFO 8947 --- [spring-boot-intro] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-10-05T18:18:04.431+01:00  INFO 8947 --- [spring-boot-intro] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 456 ms
2024-10-05T18:18:04.665+01:00  INFO 8947 --- [spring-boot-intro] [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint beneath base path '/actuator'
2024-10-05T18:18:04.703+01:00  INFO 8947 --- [spring-boot-intro] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2024-10-05T18:18:04.711+01:00  INFO 8947 --- [spring-boot-intro] [           main] c.s.s.SpringBootIntroApplication         : Started SpringBootIntroApplication in 0.9 seconds (process running for 1.025)

By default, the application will be running on localhost port 8080. If the application fails to start because that port is already in use, stop that other application and run the Spring Boot one again.

You can also change the port by adding server.port=9090, or some other available port number, to the application.properties file.

Once the application is running, if we visit http://localhost:8080 in our browser, we should be met with a Whitelabel Error Page. This is because, we are yet to define any controller to handle that request.

5. Controller

Spring Boot conforms to the Model-View-Controller (MVC) design pattern.

In MVC, the controller component receives the request, validate it and coordinate with one or more services and models and returns the correct view.

A controller, in Spring Boot, is a Java class, that’s annotated with @Controller. By convention, it is placed in the controllers package and has the Controller suffix in its name.

Let’s say we want to create a path /hello. Such that when we invoke visit http://localhost:8080/hello on a web browser, we will see a page that greets us Hello World and the current timestamp.

We will first create a controllers package and in it, create a class called HelloController.java. We will then annotate the class with @Controller.

In the HelloController.java, we will create a method in it named hello(). We will annotate this hello() method with @GetMapping("/hello").

This annotation correlates to the HTTP GET verb. It instructs Spring Boot to invoke the hello() method whenever someone visits the /hello path from a web browser.

Listing 5.1 HelloController.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Controller
public class HelloController {

    @GetMapping("/hello")
    @ResponseBody
    public String hello() {
        return "Hello World! The current local time is " + LocalDateTime.now();
    }

}

We had to use the @ResponseBody annotation so that Spring Boot will know we want to return the literal String and not a template name.

There are other annotations that we can use for each HTTP verb.

The table below shows the mapping of HTTP verb and the corresponding Spring Boot annotation:

HTTP Verb Spring Boot Annotation
GET @GetMapping
POST @PostMapping
PUT @PutMapping
PATCH @PatchMapping
DELETE @DeleteMapping

What if we want to return a JSON response from the controller, instead of a plain text? It’s easy and follows the same principle as we’ve seen before.

Let’s create a new controller class to showcase this. We will call it GreetingController.

However, we will annotate it with @RestController. This annotation will automatically return application/json content type for all the methods in the controller.

Listing 5.2 GreetingController

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

@RestController 
public class GreetingController {

    @GetMapping("/greetings")
    public Map<String, Object> hello() {
        var msg = "Hello World! The current local time is " + LocalDateTime.now();
        return Map.of("message", msg);
    }
}

If we visit http://localhost:8080/greetings from a web browser, we will see a JSON output as expected.

The fact that we annotate the class with @RestController means we no longer need to add the @ResponseBody to the method.

Did you notice that the returned Map object is being automatically converted to a JSON response without explicitly configuring it to do so?

That’s what it means to say Spring Boot comes with sensible defaults. It just works!

6. Application Configurations

The place to configure a Spring Boot application is the src/main/resources/application.properties file. It is a typical properties file, and its content a simple key = value entry. Each property is on a new line.

Let’s say we want to change the port for the application from 8080 to 9090, we only need to add server.port=8080 to the properties file and restart the application.

Listing 6.1 application.properties

1
2
spring.application.name=spring-boot-intro
server.port=9090

If you prefer to work with the YAML format, it is also supported. The difference is the file extension. Instead of application.properties, it will be application.yml.

The same configuration can now be re-written as:

Listing 6.2 application.yml

1
2
3
4
5
spring:
  application:
    name: spring-boot-intro
server:
  port: 8080

7. Conclusion

In this article, we have carefully looked at the basics of Spring Boot, its mechanisms and what makes it peculiar. This article is meant to lay a foundation that will make further readings about Spring Boot easily comprehensible.

We mentioned “convention” a few times in this article. While they’re not rules set in stone, it is crucial to understand and adhere to them.

Imagine you recently joined a new team, and they are using Spring Boot. However, the codebase looks nothing like what you’ve been learning over the years. The folder names are different, the location of files are different.

It still works though - but now you’re lost and need to spend a couple of days learning to work with the codebase. To mitigate this challenge, is why we have conventions. It makes everyone’s life easier.

For further readings, there are quality articles on specific aspects of Spring Boot on smattme.com.

You can also consult the official Spring Boot documentation here.

The complete source is available on GitHub

If you find this tutorial helpful, please share it with your connections.

Happy Coding

Seun Matt

Results-driven Engineer, dedicated to building elite teams that consistently achieve business objectives and drive profitability. With over 9 years of experience, spannning different facets of the FinTech space; including digital lending, consumer payment, collections and payment gateway using Java/Spring Boot technologies, PHP and Ruby on Rails