skip to content

Given a fresh Gradle build, show how you'd apply the Spring Boot plugin and explain why applying it alone doesn't pull in Spring dependencies.

level: juniorimportance: should knowfreq 55%

answer

  1. plugins { id("org.springframework.boot") version }
  2. plugin = tasks + packaging, not deps
  3. starters add the actual libraries
  4. BOM lets you omit versions
  5. java plugin reaction (jar disabled)

basics

~10 s

Add id("org.springframework.boot") in the plugins block. That only wires up tasks like bootJar/bootRun and the BOM; you still declare starters such as spring-boot-starter-web yourself to get actual Spring code.

solid answer

~40 s

You apply it in the `plugins {}` block: `id("org.springframework.boot") version "3.3.0"`. Applying the plugin configures *build behavior* — it registers `bootJar`/`bootWar`/`bootRun`, reacts to the `java`/`war` plugins, disables the plain `jar`, and (if present) wires `io.spring.dependency-management` with the Boot BOM. It does **not** add any application dependencies, because the plugin's job is packaging/running, not deciding what your app uses. To actually get Spring on the classpath you declare **starters**, e.g. `implementation("org.springframework.boot:spring-boot-starter-web")`. With the BOM imported you can omit versions. This separation keeps a clean line between 'how the app is built and run' (the plugin) and 'what the app depends on' (the starters you choose).

code

kotlin · 10 lines
kotlin
plugins {
    java
    id("org.springframework.boot") version "3.3.0"
}

dependencies {
    implementation(platform("org.springframework.boot:spring-boot-dependencies:3.3.0"))
    implementation("org.springframework.boot:spring-boot-starter-web")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

go deeper

for a junior

Show the plugins{} application and state that you still need starters for Spring itself.

for a middle

Explain the plugin governs build/run mechanics while starters provide capability, and how the BOM enables versionless starters.

for a senior

Discuss applying the plugin without the java plugin, plugin-vs-dependency separation of concerns, and starter composition strategy.

for a principal

Set conventions via convention plugins so all modules apply Boot + the platform consistently, centralizing version and starter governance.

## Applying the plugin Use the `plugins {}` DSL with a version on first application: ```kotlin plugins { java id("org.springframework.boot") version "3.3.0" // optional legacy: id("io.spring.dependency-management") version "1.1.5" } ``` ## What applying it does (and doesn't) do Applying a Gradle plugin runs its `apply` logic, which here: - registers tasks: `bootJar`, `bootWar`, `bootRun`, `bootBuildImage`, `bootJarMainClassName`, etc., - **reacts** to the `java` plugin (wires assemble→bootJar, disables `jar`), - imports the Boot BOM into `io.spring.dependency-management` if that plugin is applied. What it deliberately does **not** do is add `spring-context`, `spring-web`, Tomcat, Jackson, or anything else to your configurations. Packaging behavior and dependency selection are separate concerns: the plugin governs *how* the app is built and launched; *what* it contains is up to the dependencies you declare. ## Getting Spring on the classpath You pull in functionality through **starters** — curated aggregate dependencies: ```kotlin dependencies { implementation(platform("org.springframework.boot:spring-boot-dependencies:3.3.0")) implementation("org.springframework.boot:spring-boot-starter-web") // Spring MVC + embedded Tomcat implementation("org.springframework.boot:spring-boot-starter-data-jpa") // JPA + Hibernate testImplementation("org.springframework.boot:spring-boot-starter-test") } ``` Each starter transitively brings the right libraries, and the BOM pins their versions. ## Why the separation matters This means you can apply the Boot plugin to a module that is, say, a thin utility used only for `bootBuildImage` tooling, or build a custom app that uses only the starters it needs. The plugin stays focused on build/run mechanics; you compose capability via starters.

  • If you apply the Boot plugin but declare no dependencies, will the app run?
    No — bootJar would build, but with no spring-boot-starter on the classpath there's no Spring context or @SpringBootApplication machinery to launch, so bootRun has nothing meaningful to start. Starters provide the actual Spring code.
  • What does a starter give you that a single Spring artifact doesn't?
    A starter is an aggregate POM that transitively brings a curated, compatible set of libraries for a capability (e.g. starter-web brings spring-webmvc, embedded Tomcat, Jackson). It saves you from hand-picking and version-matching each piece.

saying these in an interview costs you the question

  • Believing applying the plugin auto-adds Spring to the classpath
  • Putting a version on every plugins{} entry even when a BOM/settings manages it
  • Confusing the plugin with a starter

context