RadhaPublication
HomeInterviewLearning PathsRole TracksMockBooksPricing
Login / Sign UpLog in

© 2026 Radha Publication. All rights reserved.

Shop on AmazonDonateContactPrivacyTerms
Spring Boot questions
EasySpring Boot#87 min readJul 11, 2026

What are Spring Boot Starters?

practice
learning
Practice modeTest yourself instead of reading straight through

Why interviewers love this: Starters look simple, but they reveal whether you understand how Spring Boot turns a pile of libraries into a working app.

Question: What are Spring Boot Starters?

Answer: Spring Boot Starters are pre-made dependency bundles that group the libraries you commonly need for a feature, such as web, data access, or testing. Instead of picking each jar one by one, you add one starter and get a sensible, compatible set of transitive dependencies, which are dependencies pulled in automatically by another dependency. They do not add magic by themselves; they mainly simplify dependency management and work together with Spring Boot auto-configuration.

Interview-Ready Answer: I think of Spring Boot Starters as convenient dependency bundles. For example, if I add spring-boot-starter-web, I get the typical libraries needed for building REST APIs, like Spring MVC, embedded Tomcat, and JSON support, without hunting for each version manually. The big win is consistency: starters reduce setup time, avoid version conflicts, and make the project easier to read because the intent is clear from one dependency name.

🧠 Memory Map
Memory map — visual summary of this topic

What a starter really is

A Spring Boot starter is usually a small Maven POM or Gradle metadata entry that says, “if you want this feature, pull in these related libraries together.” The starter itself is not the feature; it is the curated dependency shortcut. For example, spring-boot-starter-web points to the set of dependencies commonly needed for web apps, while spring-boot-starter-test brings in test libraries such as JUnit, AssertJ, Hamcrest, Mockito, and Spring test support.

How it works under the hood

  1. You choose a starter that matches the problem you are solving, such as web, validation, JPA, security, or tests.
  2. Your build tool resolves the starter’s transitive dependencies. This means Maven or Gradle downloads the starter plus the libraries it references.
  3. Spring Boot’s version management keeps those libraries compatible. Boot provides a tested set of versions, so you are less likely to mix jars that were never meant to work together.
  4. At runtime, Spring Boot auto-configuration looks at the classpath. Classpath means the list of classes and jars available to the application. If it sees web libraries, it configures MVC, JSON conversion, and an embedded server when appropriate.
  5. Your code starts with sensible defaults, and you only override what is truly different for your app.

Starter vs BOM vs auto-configuration

Interviewers often mix these up, so keep the roles separate. A starter is about what dependencies to add. A BOM, or Bill of Materials, is a version map that keeps related libraries aligned. Auto-configuration is the runtime behavior that creates beans and wiring based on what is on the classpath.

PieceWhat it isWhat it does
StarterDependency bundlePulls in common jars
BOMVersion catalogAligns compatible versions
Auto-configRuntime configurationCreates beans automatically

Why use starters

  • Less setup: one dependency name is faster than hunting down ten jars.
  • Fewer conflicts: Boot-curated versions reduce NoSuchMethodError and classpath mismatch problems.
  • Clear intent: starter-web tells the next developer, “this is a web app.”
  • Easy defaults: the project starts with the most common configuration already in place.

When not to rely on them blindly

Starters are convenient, but they can pull in more than you need. If you want a smaller app or a non-default server/library, you can exclude a transitive dependency and add a replacement. For example, a team might exclude embedded Tomcat and use Jetty instead. Also remember that Boot 3 moved the ecosystem to Jakarta packages, so code and dependencies that were fine in Boot 2 may need updates when upgrading.

Performance and practical notes

A starter itself has no meaningful runtime cost; it is a build-time convenience. The runtime cost comes from the libraries it brings in. More starters usually mean more classes on the classpath, which can slightly increase startup time and memory use because Spring scans more candidates for auto-configuration. In a small API with just web support, startup is often only a few seconds on a normal laptop; adding web, data, and security together can add noticeable startup time. Dependency resolution is also mostly a build-time concern, and Maven or Gradle handles it in the background.

Edge cases and gotchas

  • If you add only low-level Spring jars manually, you may miss the tested version alignment that starters give you.
  • If you add a starter and also pin unrelated library versions yourself, you can reintroduce conflicts.
  • Some starters are optional by design. For example, validation support is in spring-boot-starter-validation, not magically available everywhere.
  • A starter is not the same as auto-configuration. The starter puts libraries on the classpath; auto-configuration decides how to wire them.

Memory-friendly summary: a starter is a curated bundle of ingredients, not the finished meal. Boot gives you the groceries, the recipe is auto-configuration, and your app is the dish.

Real-World Story: Imagine a checkout service in an e-commerce system. The team uses spring-boot-starter-web for REST endpoints, spring-boot-starter-validation for request checks, and spring-boot-starter-test for tests. One day, a developer tries to “lighten” the project by replacing the starter with individual Spring jars, but misses an embedded server dependency and a Jackson library version. The app builds, but at runtime it either fails to start or begins throwing JSON serialization errors on checkout requests.

What does that look like in production? Users click “Place Order” and get 500 errors. Logs show startup failures like missing servlet infrastructure or runtime errors such as NoSuchMethodError or JSON conversion exceptions. The outage is not caused by business logic; it is caused by a dependency mismatch that the starter would have prevented. That is why teams like starters: they reduce the chance that one small dependency choice breaks the whole service.

What goes wrong if you misunderstand starters: you treat them like optional decoration instead of a safety net for dependency versions and feature bundles. Then the app becomes fragile, upgrades become risky, and every change turns into a hunt through the classpath.

Spring Boot
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.ResponseStatusException;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

// This DTO uses Bean Validation annotations.
// It compiles and works when spring-boot-starter-validation is on the classpath.
record CreateOrderRequest(
        @NotBlank String productId,
        @Min(1) int quantity
) {}

record OrderResponse(String id, String productId, int quantity, String status) {}

@Service
class OrderService {
    private final Map<String, OrderResponse> orders = new ConcurrentHashMap<>();

    OrderResponse create(CreateOrderRequest request) {
        String id = UUID.randomUUID().toString();
        OrderResponse order = new OrderResponse(id, request.productId(), request.quantity(), "CREATED");
        orders.put(id, order);
        return order;
    }

    OrderResponse findById(String id) {
        OrderResponse order = orders.get(id);
        if (order == null) {
            // A real failure path: the caller asked for an order that does not exist.
            // We return a 404 instead of a vague 500 so the API is easier to use and debug.
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Order not found: " + id);
        }
        return order;
    }
}

@RestController
@RequestMapping("/orders")
@Validated
class OrderController {
    private final OrderService orderService;

    OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping
    ResponseEntity<OrderResponse> create(@Valid @RequestBody CreateOrderRequest request) {
        // The validation starter makes this endpoint reject bad input early.
        // Example failure: quantity = 0 -> Spring returns 400 before business logic runs.
        return ResponseEntity.status(HttpStatus.CREATED).body(orderService.create(request));
    }

    @GetMapping("/{id}")
    OrderResponse get(@PathVariable String id) {
        return orderService.findById(id);
    }
}

@RestControllerAdvice
class ApiExceptionHandler {
    @ExceptionHandler(ResponseStatusException.class)
    ResponseEntity<Map<String, String>> handleNotFound(ResponseStatusException ex) {
        String message = ex.getReason() == null ? "Request failed" : ex.getReason();
        return ResponseEntity.status(ex.getStatusCode()).body(Map.of("error", message));
    }
}

Follow-up & Tricky Questions:

  • What is inside spring-boot-starter-web? It commonly brings Spring MVC, an embedded servlet container, and JSON support. The exact set is managed by Boot, so the safe answer is that it includes the libraries typically needed for REST web apps.
  • What is the difference between a starter and auto-configuration? A starter adds dependencies to the classpath, while auto-configuration creates and wires beans at runtime based on those dependencies.
  • Can I create my own starter? Yes. Teams often build custom starters for internal logging, security, or cloud setup by packaging a shared dependency set and optional auto-configuration.
  • Why use spring-boot-starter-parent if starters already exist? The parent helps manage plugin and dependency versions, while starters are the feature-focused dependency bundles you add to the project.
  • How do I remove something a starter brings in? Use dependency exclusions. For example, if a starter pulls in a server or logging library you do not want, exclude that transitive dependency and add your preferred replacement.
  • Tricky: Is a starter a JAR full of framework code? Usually no. It is mainly a dependency descriptor that points to the real libraries you want.
  • Tricky: Does adding spring-boot-starter-web always mean I use Tomcat? Not always. Tomcat is the default embedded server in the standard web starter, but you can exclude it and use another server if your build is set up that way.
  • Tricky: Do starters guarantee zero version problems? They greatly reduce risk, but you can still create conflicts if you override managed versions carelessly or mix incompatible third-party libraries.

Common Mistakes:

  • Mistake: Treating a starter as a feature by itself. Correction: It is a dependency bundle; the real behavior comes from the libraries and auto-configuration it enables.
  • Mistake: Manually adding lots of low-level jars and skipping starters. Correction: Use starters first, because they are the shortest path to a compatible, Boot-managed setup.
  • Mistake: Thinking all starters are for runtime only. Correction: Some, like spring-boot-starter-test, are for tests and belong in test scope.
  • Mistake: Ignoring transitive dependencies. Correction: Starters are valuable because they pull in the right supporting jars automatically.

Memory Hook: Think of a starter like a restaurant combo meal: one order gives you the main item, sides, and drink in matching sizes. You are not getting a magic kitchen; you are getting a well-chosen bundle that makes the meal easy and consistent.

Cheat Sheet:

  • Starter = curated dependency bundle.
  • It reduces manual dependency selection.
  • Boot manages compatible versions for you.
  • Auto-configuration uses the classpath created by the starter.
  • Use web, data-jpa, security, validation, and test starters for common cases.
  • Exclude transitive jars when you need a different server or library.

Practice Tasks:

  • Create a small REST API using only spring-boot-starter-web and run one GET endpoint.
  • Add spring-boot-starter-validation and make one request fail with a 400 when input is invalid.
  • Replace one starter dependency with manual jars and observe how much more setup and version management you need.
Previous
Back to Questions←→to navigate
Next

Recommended Resources

Recommended Book

Cracking the Coding Interview

189 Programming Questions and Solutions

Recommended Book

Cracking the Coding Interview

189 Programming Questions and Solutions

import jakarta.validation.Valid; import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.server.ResponseStatusException; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } // This DTO uses Bean Validation annotations. // It compiles and works when spring-boot-starter-validation is on the classpath. record CreateOrderRequest( @NotBlank String productId, @Min(1) int quantity ) {} record OrderResponse(String id, String productId, int quantity, String status) {} @Service class OrderService { private final Map<String, OrderResponse> orders = new ConcurrentHashMap<>(); OrderResponse create(CreateOrderRequest request) { String id = UUID.randomUUID().toString(); OrderResponse order = new OrderResponse(id, request.productId(), request.quantity(), "CREATED"); orders.put(id, order); return order; } OrderResponse findById(String id) { OrderResponse order = orders.get(id); if (order == null) { // A real failure path: the caller asked for an order that does not exist. // We return a 404 instead of a vague 500 so the API is easier to use and debug. throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Order not found: " + id); } return order; } } @RestController @RequestMapping("/orders") @Validated class OrderController { private final OrderService orderService; OrderController(OrderService orderService) { this.orderService = orderService; } @PostMapping ResponseEntity<OrderResponse> create(@Valid @RequestBody CreateOrderRequest request) { // The validation starter makes this endpoint reject bad input early. // Example failure: quantity = 0 -> Spring returns 400 before business logic runs. return ResponseEntity.status(HttpStatus.CREATED).body(orderService.create(request)); } @GetMapping("/{id}") OrderResponse get(@PathVariable String id) { return orderService.findById(id); } } @RestControllerAdvice class ApiExceptionHandler { @ExceptionHandler(ResponseStatusException.class) ResponseEntity<Map<String, String>> handleNotFound(ResponseStatusException ex) { String message = ex.getReason() == null ? "Request failed" : ex.getReason(); return ResponseEntity.status(ex.getStatusCode()).body(Map.of("error", message)); } }