What Spring Boot does for you
Think of moving into a furnished apartment. The kitchen already has a fridge and a stove, the bedroom a bed. You can replace any of them, but you can start living there on day one.
Spring is a large toolbox for Java and Kotlin backends: web, databases, security, messaging. Spring Boot is the furnished apartment built from it. It picks sensible defaults, wires the pieces together and includes a web server, so a working backend is a few lines of code. When a default doesn’t fit, you replace just that piece.
Spring Boot is an opinionated layer over the Spring Framework with three mechanisms:
- Starters: curated dependency sets with aligned versions (the Boot BOM manages hundreds of library versions for you).
- Auto-configurationAuto-configurationSpring Boot's mechanism that creates and configures beans for you when a library is on the classpath and you haven't defined your own.Open in glossary →:
@Configurationclasses shipped with Boot, each guarded by conditions (@ConditionalOnClass,@ConditionalOnMissingBean,@ConditionalOnProperty). They create beans only when a library is on the classpath and you haven’t defined your own. - An embedded server (Tomcat by default) and an executable jar, so the app runs with
java -jarinstead of being deployed into a server.
Everything else is plain Spring: an ApplicationContext that creates and wires beans.
A complete backend
@SpringBootApplication
class ShopApplication
fun main(args: Array<String>) {
runApplication<ShopApplication>(*args)
}
@RestController
class HelloController {
@GetMapping("/hello")
fun hello(@RequestParam(defaultValue = "world") name: String) =
mapOf("message" to "Hello, $name!")
}@SpringBootApplication
public class ShopApplication {
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
}
@RestController
class HelloController {
@GetMapping("/hello")
public Map<String, String> hello(@RequestParam(defaultValue = "world") String name) {
return Map.of("message", "Hello, " + name + "!");
}
}Run it (./mvnw spring-boot:run or ./gradlew bootRun) and open http://localhost:8080/hello?name=Ana:
{ "message": "Hello, Ana!" }What each piece does:
@SpringBootApplicationmarks the starting class. Spring looks for your other annotated classes in its package and the packages below it.mainstarts Spring, which starts a web server on port 8080.@RestControllersays “this class answers HTTP requests, and what its methods return is the response body”.@GetMapping("/hello")connectsGET /helloto the method.- The
Mapyou return is turned into JSON automatically, because the web starter includes Jackson, a JSON library, and Boot configured it.
The two lines that made all of this possible are in your build file: the starters.
Starters: features by dependency
// build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-actuator")
}<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>A starter is a bundle of libraries for one job, in versions that work together. spring-boot-starter-web brings the web framework, the Tomcat server and Jackson; spring-boot-starter-actuator adds health and metrics endpoints, like /actuator/health. You don’t write version numbers: Spring Boot picks them.
The easiest way to start a project is start.spring.io: pick Java or Kotlin, Maven or Gradle, tick the starters you need, and download a ready project.
Dev note
spring-boot-starter-webmvc; the old name still works.How auto-configuration decides
@SpringBootApplication is three annotations: @SpringBootConfiguration (this is a configuration class), @ComponentScan (scan this package and below) and @EnableAutoConfiguration. The last one loads the classes listed in every jar’s META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports and evaluates their conditions:
@AutoConfiguration
@ConditionalOnClass(ObjectMapper::class) // only if Jackson is on the classpath
class JacksonAutoConfiguration {
@Bean
@ConditionalOnMissingBean // only if you didn't define one
fun jacksonObjectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper =
builder.build() // spring.jackson.* properties applied here
}@AutoConfiguration
@ConditionalOnClass(ObjectMapper.class) // only if Jackson is on the classpath
public class JacksonAutoConfiguration {
@Bean
@ConditionalOnMissingBean // only if you didn't define one
ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.build(); // spring.jackson.* properties applied here
}
}That back-off rule is the whole design: your bean always wins. It’s also the most common surprise. Define your own ObjectMapper to change one setting, and Boot’s whole Jackson setup steps aside, including every spring.jackson.* property and the modules it registered. Prefer the extension points Boot offers (a Jackson2ObjectMapperBuilderCustomizer, a RestClientCustomizer, a property) over replacing a bean.
To see what was configured and why, start with --debug (or debug=true) for the conditions evaluation report, or call /actuator/conditions.
Dev note
JsonMapper and customizers are JsonMapperBuilderCustomizer. The back-off rule is the same.- Boot = starters (version-aligned dependency sets) + auto-configuration + embedded server + executable jar. Underneath, it’s a plain
ApplicationContext. @SpringBootApplication=@SpringBootConfiguration+@EnableAutoConfiguration+@ComponentScan(its package and below).- Auto-configs are conditional (
@ConditionalOnClass,@ConditionalOnMissingBean,@ConditionalOnProperty) and back off when you define the bean yourself, taking their properties with them. Prefer customizers. - Debug it with
--debug(conditions report) or/actuator/conditions.
Check this part
What does a starter like
spring-boot-starter-webgive you?What does
@RestControllerwith@GetMapping("/hello")do?You define your own
ObjectMapperbean to change one setting. What happens tospring.jackson.*properties?How do you find out why an auto-configuration did or didn't apply?