Getting Started with Spring Boot
Source: Spring Boot in Practice — Chapter 1 (§1.3–1.4) by Somnath Musib (Manning). Concepts rewritten for this course; sample project: spring-boot-app-demo.
You know what Spring Boot is for — this lesson is about generating a project, reading its layout, and understanding the pieces Initializr creates before you write business logic.
These editors do not compile or run Spring Boot. Check validates patterns in your code (sourceChecks) only. Annotated snippets above each exercise show the usual shape — inline comments explain what each part does; you still type it into the editor yourself. Paste is disabled (keyboard, right-click, drag-drop) so you practice writing the code.
What this lesson covers
- Creating a project with Spring Initializr
- Standard Maven layout and what each folder is for
pom.xml: parent POM, starters, and the Boot Maven plugin- The main class:
@SpringBootApplicationandSpringApplication application.properties/ YAML- Executable JAR layout and graceful shutdown
- Brief preview: startup events, Actuator, DevTools
1. Your first Spring Boot project
Spring Initializr (start.spring.io) generates a skeleton app: pick Java version, build tool, packaging, and starters (curated dependency bundles). IDEs embed the same API so you can generate projects without leaving the editor.
Typical choices for a web API:
| Initializr field | Common choice |
|---|---|
| Project | Maven |
| Language | Java |
| Spring Boot | Current stable (book examples often use 2.4.x; use 3.x for new work) |
| Packaging | Jar |
| Java | 17+ (LTS) |
| Dependencies | Spring Web, Spring Boot DevTools (optional), Spring Boot Actuator (optional) |
Download the zip, unzip, and open it in your IDE — or clone the book’s demo repo.
Run locally (from the directory with pom.xml):
./mvnw spring-boot:run
Default HTTP port is 8080 unless you override it in config.
Spring Initializr
1 / 2What does selecting spring-boot-starter-web on Initializr mainly give you?
Pick an answer to see if you are right.
2. Project structure
A generated Boot app is intentionally small:
my-app/
├── pom.xml # dependencies, parent, plugins
├── mvnw, mvnw.cmd # Maven wrapper
├── src/main/java/ # application source (main class lives here)
├── src/main/resources/ # application.properties, static files, templates
└── src/test/java/ # tests (often one empty @SpringBootTest class)
| Piece | Role |
|---|---|
pom.xml | Declares parent, starters, Java version, spring-boot-maven-plugin |
src/main/java | Your code; Initializr creates …Application with main |
src/main/resources | Config files; empty application.properties by default |
src/test/java | JUnit tests; spring-boot-starter-test on the classpath |
Package naming follows reverse domain (com.example.demo). The main class is usually named {AppName}Application.
3. The pom.xml file
Three areas matter most: parent, dependencies, build plugin.
3.1 Parent: spring-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
The parent is a special “starter” POM that supplies:
- Default Java version and compiler settings
- Dependency management — you omit versions on Boot-managed artifacts
- Sensible defaults for plugins (Surefire, etc.)
Already have a corporate parent POM? You cannot inherit two parents. Import Boot’s BOM instead:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
You still add spring-boot-maven-plugin explicitly in <build>.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type> <!-- import the BOM, not a jar -->
<scope>import</scope> <!-- merge Boot's version catalog without starter-parent -->
</dependency>
</dependencies>
</dependencyManagement>
3.2 Starter dependencies
Starters group dependencies for a feature area and pin compatible versions. spring-boot-starter-web pulls Spring MVC, Jackson, and embedded Tomcat — you run with main(), not by deploying a WAR to an external server (WAR packaging is still supported if you need it).
Starters can depend on other starters (starter-web → starter, starter-tomcat, starter-json). You pick capabilities on Initializr; Boot handles the graph.
Generated projects often include:
spring-boot-starter-web— runtime web stackspring-boot-starter-test— JUnit 5, Mockito, AssertJ, etc. (testscope)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- MVC + Jackson + embedded Tomcat; omit version when parent/BOM manages it -->
</dependency>
3.3 Spring Boot Maven plugin
spring-boot-maven-plugin adds goals such as:
| Goal | Purpose |
|---|---|
spring-boot:run | Run the app in place (compile + start) |
spring-boot:repackage | Turn the packaged JAR into an executable fat JAR (bound to package phase) |
spring-boot:build-image | Build an OCI container image |
mvn package produces an executable JAR because repackage runs after the plain JAR is built.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- adds spring-boot:run and repackages an executable fat JAR at package -->
</plugin>
</plugins>
</build>
pom.xml quiz
1 / 2Why can you omit version numbers on spring-boot-starter-* dependencies?
Pick an answer to see if you are right.
4. The main application class
Initializr generates a class named like DemoApplication in your base package:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4.1 Why main() is enough for a web app
Boot embeds Tomcat (via spring-boot-starter-tomcat transitively). Calling main starts the servlet container in-process — no separate app-server install for local dev.
4.2 @SpringBootApplication
Convenience meta-annotation combining:
| Annotation | Effect |
|---|---|
@SpringBootConfiguration | Marks config; meta-@Configuration |
@EnableAutoConfiguration | Auto-config beans from classpath (starters trigger configs) |
@ComponentScan | Scan current package and sub-packages for @Component, @Service, etc. |
Components outside the base package tree are not picked up unless you widen scan settings.
4.3 SpringApplication.run
Bootstrap sequence (simplified):
- Create an
ApplicationContextsuited to the app type (Servlet web, Reactive, or plain) - Register command-line args as a property source
- Refresh the context — load singleton beans
- Run
ApplicationRunner/CommandLineRunnerbeans
You can customize bootstrap:
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
app.run(args);
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // @Configuration + @EnableAutoConfiguration + @ComponentScan
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args); // bootstrap context + embedded server
}
}
5. application.properties and YAML
src/main/resources/application.properties externalizes config as key=value:
server.address=localhost
server.port=8081
Equivalent YAML (application.yml):
server:
address: localhost
port: 8081
Change server.port, restart, and the embedded server binds to the new port. Full property list: Spring Boot application properties.
server.port=9090 # HTTP port for embedded Tomcat (server.* namespace)
6. Executable JAR
mvn clean package
java -jar target/demo-1.0.0.jar
Plain mvn package alone would not produce a runnable JAR — repackage nests dependencies and sets the manifest launcher.
Fat JAR layout (conceptual):
demo.jar
├── META-INF/MANIFEST.MF # Main-Class → Boot loader; Start-Class → your @SpringBootApplication
├── org/springframework/boot/loader/…
└── BOOT-INF/
├── classes/ # your .class files
└── lib/ # dependency JARs
classpath.idx and layers.idx help ordered loading and container image layering (Docker/OCI builds later in the book).
7. Shutting down gracefully
Foreground run: Ctrl+C stops the JVM immediately (server.shutdown=immediate by default) — in-flight requests may be cut off.
For graceful drain:
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
New requests stop; existing work gets up to 30s to finish.
server.shutdown=graceful # drain in-flight work instead of stopping immediately
spring.lifecycle.timeout-per-shutdown-phase=30s # cap how long each shutdown phase waits
8. Preview: events, Actuator, DevTools
These topics get full chapters later — know the names now.
8.1 Startup events
Boot publishes lifecycle events (ApplicationStartingEvent, ApplicationEnvironmentPreparedEvent, ApplicationReadyEvent, ApplicationFailedEvent, …). Subscribe with @EventListener for most; very early events need ApplicationListener registered on SpringApplication or via META-INF/spring.factories / META-INF/spring/org.springframework.context.ApplicationListener.imports (Boot 3).
@EventListener(ApplicationReadyEvent.class)
public void onReady(ApplicationReadyEvent event) {
// safe to assume app can serve traffic
}
@EventListener does not fire for the earliest events (before the context exists).
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
@Component
public class StartupHooks {
@EventListener(ApplicationReadyEvent.class) // fires when the app can serve traffic
public void ready(ApplicationReadyEvent event) {
}
}
8.2 Actuator
Add spring-boot-starter-actuator for production-ready endpoints (/actuator/health, /actuator/info, …). Expose more over HTTP with management.endpoints.web.exposure.include (use carefully in production).
8.3 DevTools
spring-boot-devtools (optional) restarts the app on classpath changes and offers LiveReload for static assets during development.
8.4 Later in the book
Custom starters, auto-configuration, and FailureAnalyzer implementations extend the same Boot infrastructure — same idea as official starters, but for your organization’s shared modules.
Events and tooling
1 / 3@SpringBootApplication combines which three concerns?
Pick an answer to see if you are right.
Checklist before lesson 1
| Topic | You should know |
|---|---|
| Initializr | Generate project, pick starters, run with mvnw spring-boot:run |
pom.xml | Parent or BOM, starters, spring-boot-maven-plugin |
| Main class | @SpringBootApplication, SpringApplication.run, embedded Tomcat |
| Config | application.properties / YAML, server.port |
| Packaging | mvn package → executable JAR via repackage |
| Shutdown | server.shutdown=graceful + timeout for drain |
| Next | Lesson 1 — configuration, logging, validation, startup hooks in depth |