I’m a fan of Java. If you haven’t given it a chance in a while, you may not have noticed that, Java has quietly been adopting some of the best practices that make dynamic and functional languages so appealing, without sacrificing the many hundred person-years of effort that have made Java and the JVM a world-class development environment. Java is still one the world’s most popular programming languages with roughly 9 million programmers using Java. It doesn’t make sense to ignore all of that history and development effort because of a niggling feeling that Java is a little too verbose, or that XML is so last year.
Yet it can still be difficult to convince people that Java is a valid choice for modern web development. Compounding this problem is the sheer volume of choice for newbie Java developers — it can be simply overwhelming to get started with Java. This post attempts to cut through the noise by providing an opinionated starting point for building a modern Java web application using Spring Boot and Visual Studio Code. Follow along with me as we go from nothing but an editor window to a full-fledged, performant, testable, and secure web application built with Spring Boot and Java.
Part 1: Setting Up
Java development on Visual Studio Code (VS Code) requires a few extensions to be installed for an optimal experience. Thankfully, if you get stuck anywhere along the way, the VS Code documentation provides an excellent tutorial.
Installing the Java Extension Pack for Visual Studio Code
In contrast to IDEs such as IntelliJ or Eclipse, the concept of a “Java project” is entirely foreign to Visual Studio Code. Instead, VS Code provides extensions to support Java projects. Depending on the popularity of the language, the extension marketplace for VS Code can be a bit of a minefield of unsupported, deprecated, or just broken projects. Thankfully, Microsoft curates or maintains extensions for most popular languages, and a recent addition to the extension marketplace includes the concept of packs — collections of extensions that work well together to fully support a language.
The Java Extension
is maintained by Microsoft and bundles the most popular VS Code extensions for
Java in one place. To get started with Java in VS Code, install the Java
Extension Pack by navigating to the extension in the
or do it through VS Code itself by opening the extension sidebar with
CTRL+SHIFT+X, searching for Java Extension Pack, and clicking install.
After the necessary Java extensions are installed, opening a VS Code workspace that contains Java artifacts will cause those extensions to load and understand those artifacts and present options for working with them.
Installing Spring Boot Extensions
Spring and Spring Boot are additional libraries and frameworks for building Java
applications. Like Java itself, VS Code knows nothing about Spring and requires
extensions to support it. There are three extensions in particular that are
worth installing to provide full support for Spring Boot: Spring Initializr,
Spring Boot Tools, and Spring Boot Dashboard. Spring
is an extension to generate a Spring Boot project and maintain Spring Boot
dependencies. Spring Boot
provides additional support for editing
.yml files for
Spring Boot projects, and the extension provides additional support for editing
.java files in Spring projects. Lastly, Spring Boot
provides a view to manage Spring Boot projects in your workspace, allowing you
to quickly start, stop or debug a Spring Boot project.
Go ahead and install these extensions. They will help us get started with Spring Boot.
Configuring the JDK
You can configure the JDK used by VS Code using the
Java: Configure Java Runtime command. To do this, bring up the Command Palette with
Java: Configure Java Runtime to select the command. From here you can
install a JDK and view or update your settings to make sure that the environment
JAVA_HOME are set correctly. To set environment
variables in Windows, follow this
For macOS or Linux, follow this
Part 2: Creating a Basic Spring Boot Project
Spring comes with a tool called Spring initializr which is available online at
https://start.spring.io/ and is integrated into VS
Code through the Spring
extension we installed earlier. You can run the Initalizr through the VS Code
Command Palette (
CTRL+SHIFT+P) and type
Spring Initializr: Generate a Maven Project. Follow the prompts to create your project with these settings:
- Specify a project language.
- Input Group Id for your project. I used
- Input Artifact Id for your project. I used
- Specify Spring Boot version.
- Search for dependencies. Select
Spring Boot DevToolsand
Create your project in a new folder to get started. Once done, you can open the
project folder in VS Code. On the left-hand sidebar in File Explorer mode you
can see a
Spring-Boot Dashboard heading. Within this heading you can start and
stop your Spring Boot application. You can also use the standard VS Code run
configuration created for you in
Go ahead and start the application using the Spring-Boot Dashboard, which runs
an embedded Tomcat server instance making your application available from
localhost:8080. Navigate to that URL using your browser to see your running
Tomcat server (which throws an error because nothing is implemented yet).
What did Spring Initializr do to me?
Although it’s nice to get up and running quickly, I tend to be distrustful of magic, so let’s dive deeper into the starter project to uncover what Spring Initializr did for us.
During setup, we told Spring Initializr to add the Spring Boot DevTools and
Spring Web dependencies. You can see these dependencies, along with a starting
test framework in the
pom.xml file created for your project:
Spring Boot DevTools
Spring Boot DevTools provides some opinionated configuration and tooling that
can make the development experience a little better. First, DevTools sets some
default properties for Spring libraries to disable caching during local
development, and to log web requests at the
DEBUG logging level. The full set
of property defaults configured by DevTools is available on
Most dynamic programming languages provide a live reload development environment that automatically updates the code running on the server whenever code changes in the file system. DevTools provides this functionality by restarting the application server any time the classpath is modified. This restart can be combined withDevTools a browser refresh whenever a file is changed. You can install the LiveReload browser extensions to have the browser automatically refresh after any changes are detected.
The Spring Web dependencies is a container for a few different libraries that aid in web development. Specifically, Spring Web uses Spring MVC as a model-view-controller pattern, Jackson for JSON processing, and an embedded Tomcat server, along with the required configuration for servlet handling, error pages, and bundling your application as a WAR file for deployment to the Tomcat servlet container.
In addition to setting up the required dependencies, Spring Initializr created a
default Application based on your configuration. In my case, this file was
DemoApplication with the sole job of running your Spring app.
public static void main method, we have a single line:
SpringApplication.run. The SpringApplication class provides a convenient way
to bootstrap a Spring application that is started from a main() method using the
@SpringBootApplication annotation on your main class enables some of
Spring Boot’s opinionated parts. This annotation, is actually just a combination
of three annotations:
@Configuration: Allows us to import additional configuration classes and beans.
@EnableAutoConfiguration: Automatically configures your application based on the chosen dependencies.
@ComponentScan: Automatically register Beans and Components to be managed by Spring’s IoC container. If you are not familiar with Spring Bean’s, consult this tutorial.
Structuring the rest of your application
Spring Initializr created a default main class. To add to this application, you
keep the main class as the root of your project and add packages and classes as
subdirectories of this main application. With this structure, the
@SpringBootApplication in the main class defines a base package to search for
additional Spring components using the
To continue building your example, the recommended application structure looks something like this:
com +- sookocheff +- DemoApplication.java | +- customer | +- Customer.java | +- CustomerController.java | +- CustomerService.java | +- CustomerRepository.java | +- order +- Order.java +- OrderController.java +- OrderService.java +- OrderRepository.java
Part 3: A Simple Web Service
Now that we have a project setup and integrated with VS Code, we can create a
simple web service. To do this, we will create simple REST endpoint that returns
a JSON payload representing a
basic data model is defined in a simple
With this basic data model in place, we can serve requests. The Spring Web
dependency adds the Spring MVC library implementing our model-view-controller
pattern for handling web requests. HTTP requests are handled by a controller
identified by the
@RestController annotation, and individual URLs are handled
This simple application can be run using the Spring Dashboard or run
configuration. Navigate to
localhost:8080/player to view the simple response.
What magic happened here?
Navigating to the
/player URL provides a fully serialized JSON response for the
basic Player class we defined. How did this happen? Spring Boot works by looking
at the classpath of your project and at any of the beans or components you have
configured and connects those pieces together into a working application.
When we use the
@SpringBootApplication we transitively add the
@EnableAutoConfiguration annotation tells
Spring Boot to “guess” how you will want to configure Spring, based on our
dependencies. For example, our project includes Spring MVC on the classpath
because it was included as part of the
Once Spring Boot sees this dependency on the classpath, it adds the proper
configuration to your application to setup Spring Web MVC with sane defaults.
The Spring Web MVC framework is designed around a
handles all the HTTP requests and responses. Spring Web MVC also requires a
WebApplicationContext that tracks the instantiation of controllers and
handlers. In a traditional Spring application, these components are configured
What Spring Boot does for us is convert the XML-based configuration of a
traditional Spring app with code-based annotations and sane defaults. If, at any
time, you want to make changes to the sane defaults you can tell Spring Boot to
not auto-configure a certain component by using an
exclude parameter to the
@SpringBootApplication annotation. The full list of auto configuration and how
it works is available in the Spring Boot reference
Where to go next?
Spring Boot (and Spring) is a big project, and it is hard to understand something of this scope in a single afternoon. If you want to learn more, the reference documentation for both Spring and Spring Boot are excellent resources.