Spring Boot, starters and auto-configuration
Spring Boot is what makes Spring pleasant to start with, and it does so through three things: starters (dependency bundles), auto-configuration (sensible defaults wired up for you), and an embedded server (your app is a plain executable). This is the biggest source of Spring's "magic" reputation — you add a dependency and suddenly things work — so this lesson explains the mechanism, so it stops being magic and becomes something you can reason about and, when needed, override.
Starters: curated dependency bundles
A starter is a single dependency that pulls in a coherent set of libraries for a job, at versions known to work together. Instead of hunting for the right versions of a dozen web libraries, you add one line:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web brings in Spring MVC, an embedded Tomcat server, JSON handling (Jackson), and
validation glue — everything to build a REST API — all at compatible versions. The starters you meet in
this course:
| Starter | Brings |
|---|---|
spring-boot-starter-web |
Spring MVC, embedded Tomcat, JSON — REST APIs |
spring-boot-starter-data-jpa |
Spring Data JPA, Hibernate — persistence |
spring-boot-starter-security |
Spring Security — auth |
spring-boot-starter-validation |
Bean Validation |
spring-boot-starter-test |
JUnit 5, Mockito, Spring test support |
Notice the starters have no version numbers in the snippet above. That is because the Spring Boot parent (or the dependency-management import) sets versions for you — a single Boot version pins the whole compatible set. This is a real problem solved: "dependency hell", where libraries need conflicting versions of each other, is largely gone because Boot curates a known-good set per release. You upgrade one number (the Boot version) and the whole stack moves together.
Auto-configuration: defaults that react to your classpath
Auto-configuration is the heart of the "magic". When Spring Boot starts, it looks at what is on your classpath and configures sensible defaults accordingly:
- You added
starter-web→ there is a servlet API on the classpath → Boot auto-configures an embedded Tomcat, aDispatcherServlet, JSON converters. You get a working web server with zero configuration. - You added
starter-data-jpaand an H2 driver → Boot auto-configures a datasource, anEntityManagerFactory, a transaction manager, pointed at an in-memory H2 database. - You added
starter-security→ Boot auto-configures a default security filter chain (everything locked down, a generated password) until you configure your own.
The mechanism, stated plainly so it is not magic: Boot ships auto-configuration classes that are
conditional — each says "if such-and-such class is on the classpath, and the user has not already
defined this bean, then create this default". @ConditionalOnClass, @ConditionalOnMissingBean and friends
drive it. So auto-configuration is not spooky action — it is a pile of configuration classes that switch on
based on what they detect and back off the moment you provide your own. Your configuration always wins:
define your own datasource bean and Boot's default steps aside. That "back off if the user did it" rule is
why auto-configuration is safe — it gives you defaults without ever fighting your explicit choices.
The embedded server: your app is the executable
Traditional Java web apps were packaged as a .war file and deployed into a separate server (Tomcat,
JBoss) that you installed and managed. Spring Boot flips this: the server is embedded inside your
application. You build a single executable JAR that contains Tomcat, and you run it like any program:
java -jar dakiya.jar # the app starts its own web server on port 8080
No separate server to install, configure or deploy into. This is what makes Spring Boot apps easy to run locally (just run the main class), easy to containerise (one JAR in a container), and suited to microservices (each service is a self-contained executable). The embedded server is a big part of why "Boot" made Spring approachable.
Configuration: overriding the defaults
Auto-configuration gives defaults; you override them in application.properties (or application.yml)
without writing code:
server.port=9090 # run on 9090 instead of 8080
spring.datasource.url=jdbc:postgresql://localhost:5432/dakiya
spring.jpa.hibernate.ddl-auto=validate
logging.level.org.springframework.web=DEBUG
These property keys are how you tune auto-configured components — the port, the database URL, logging
levels, and hundreds more. When you need to replace a default entirely (not just tune it), you define your
own bean and, per the "your config wins" rule, Boot's default backs off. So the layering is: Boot's
auto-configuration provides defaults; application.properties tunes them; your own beans replace them.
That gradient — from "works out of the box" to "fully under your control" — is exactly what lets you start
fast and take over as your needs grow.
Check your work
Starters. Single dependencies that bundle a coherent, version-compatible set of libraries for a job
(starter-web = MVC + Tomcat + JSON); versions come from the Boot parent, so one Boot version pins the
whole stack — dependency hell largely solved.
Auto-configuration. Boot inspects the classpath and creates sensible default beans — a web server from
starter-web, a datasource from starter-data-jpa + a driver. The mechanism is conditional configuration
classes (@ConditionalOnClass, @ConditionalOnMissingBean) that switch on by detection and back off when
you define your own — your config always wins.
Embedded server. The server (Tomcat) is inside your app; you build one executable JAR and java -jar it
— no separate server to install; ideal for local dev, containers, microservices.
Configuration layering. Auto-config provides defaults → application.properties/.yml tunes them
(port, datasource, logging) → your own beans replace them entirely.
Practice
- Add
spring-boot-starter-web, run the app, and confirm a web server starts on port 8080 with no configuration — auto-configuration at work. - Set
server.portinapplication.propertiesand confirm the port changes — tuning a default. - Add
starter-data-jpaand an H2 dependency, and observe Boot auto-configure an in-memory database (watch the startup log). - Look at a starter's dependency tree (
./mvnw dependency:tree) and see how many libraries one starter pulls in, all at compatible versions. - Define your own bean of a type Boot auto-configures and confirm (via a log or the actuator) that Boot's default backed off — "your config wins".
- Explain, in terms of
@ConditionalOnClass, why adding a dependency can make new behaviour appear.
Official documentation
- Spring Boot — Starters — The full list and what each bundles.
- Spring Boot — Auto-configuration — How it works and how to override it.
- Spring Boot — Common application properties — Every property you can set.
Next: your first Spring Boot application.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship