HomeSpring BootSpring Boot Features: Complete Overview With Examples
Spring Boot

Spring Boot Features: Complete Overview With Examples

Overview of the core Spring Boot features: auto-configuration, starters, profiles, embedded server, Actuator, DevTools, graceful shutdown, testing and logging. Short examples, when to use each, and links to the deep dives.

What Makes Spring Boot a Complete Platform

Spring Boot is more than a shortcut for configuring the Spring Framework. Its features cover the whole application lifecycle: - Start a project: Spring Initializr, starters, CLI - Develop: auto-configuration, DevTools - Configure: externalized configuration, profiles - Run: embedded server, graceful shutdown, logging - Operate: Actuator (health, metrics, diagnostics) - Verify: sliced test contexts This page is the overview. Each feature gets a short explanation, a minimal example and guidance on when to use it, and links to the dedicated tutorial. Code targets Spring Boot 3.x on Java 17+.

Spring Boot Features at a Glance

| Feature | Problem it solves | Key setting or entry point | |---|---|---| | Starters | Dependency version juggling | spring-boot-starter-* | | Auto-configuration | Boilerplate bean setup | @SpringBootApplication | | Externalized configuration | One JAR, many environments | application.yml, env vars, CLI args | | Profiles | Environment-specific beans and settings | spring.profiles.active | | Embedded server | No external Tomcat or WAR deployment | server.* | | Actuator | Health, metrics, runtime diagnostics | management.* | | DevTools | Slow edit-run-test loop | spring-boot-devtools | | Graceful shutdown | Dropped requests during deploys | server.shutdown=graceful | | Testing slices | Slow, unfocused tests | @WebMvcTest, @DataJpaTest | | Logging | Production logging without XML | logging.* | | CLI and Initializr | Project bootstrapping | spring init, start.spring.io |

1. Starters and Auto-Configuration

Starters are curated dependency bundles. Add `spring-boot-starter-web` and you get Spring MVC, Jackson and Tomcat with compatible versions. Auto-configuration then inspects your classpath, beans and properties and registers what the application most likely needs. Every auto-configuration is conditional, so it backs off as soon as you define your own bean. Use it for sensible defaults. When behaviour surprises you, run with `debug=true` or open `/actuator/conditions` to see what was applied and what was skipped.
Java
// Add spring-boot-starter-data-jpa and Boot configures the connection pool,
// EntityManagerFactory, Spring Data repositories and transaction manager.

// Define your own bean and the auto-configured one backs off:
@Bean
public DataSource dataSource() {
    return DataSourceBuilder.create()
        .url("jdbc:mysql://localhost:3306/mydb")
        .username("root")
        .password(System.getenv("DB_PASSWORD"))
        .build();
}

// Exclude an auto-configuration explicitly:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class Application { }

2. Externalized Configuration and Profiles

Externalized configuration lets the same JAR run in every environment. Properties come from files, environment variables and command-line arguments, and higher-precedence sources override lower ones (command-line arguments beat environment variables, which beat application.properties). Profiles select environment-specific files (`application-prod.yml`) and beans (`@Profile`). Bind related settings to a validated `@ConfigurationProperties` class instead of scattering `@Value` annotations. Never commit secrets or a hardcoded `spring.profiles.active=prod`. Supply both from the environment.
yaml
# application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    password: ${DB_PASSWORD}      # from the environment

# Activate a profile at runtime:
#   SPRING_PROFILES_ACTIVE=prod java -jar app.jar

3. Embedded Web Server

The server runs inside your JAR, so deployment is `java -jar app.jar`. There is no external Tomcat and no WAR file. Tomcat is the default, and Jetty and Undertow are drop-in alternatives. Stay with Tomcat unless you have a concrete reason to switch. Most tuning is done with properties. Note that older tutorials still show `server.tomcat.max-threads`, which was renamed `server.tomcat.threads.max` in Boot 2.3. If TLS is terminated at a load balancer or ingress, you don't need to configure SSL in Boot.
application.properties
server.port=8080
server.servlet.context-path=/api
server.tomcat.threads.max=200
server.tomcat.connection-timeout=5s
server.compression.enabled=true

# Only if the application terminates TLS itself:
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=${KEYSTORE_PASSWORD}
server.ssl.key-store-type=PKCS12

4. Actuator

Actuator adds production-ready endpoints: health, metrics, environment, loggers, thread dumps and more. Kubernetes liveness and readiness probes can use the health groups directly, and metrics are published through Micrometer to Prometheus, Grafana or Datadog. Security warning: do not expose every endpoint publicly. `env`, `beans` and `heapdump` can leak sensitive data. Expose `health`, `info` and `metrics` by default and secure the rest.
application.properties
# Production-safe default
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when-authorized
management.endpoint.health.probes.enabled=true

# Change a log level at runtime, no restart:
#   POST /actuator/loggers/com.example   {"configuredLevel": "DEBUG"}

5. DevTools

DevTools shortens the development loop. Saving a file restarts only the application classloader (typically 1-2 seconds instead of 10+), LiveReload refreshes the browser, and development defaults such as disabled template caching are applied automatically. It is disabled automatically when you run a packaged JAR. Mark the dependency optional so it stays out of the artifact anyway.
XML
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

6. Graceful Shutdown

With graceful shutdown, the server stops accepting new requests on SIGTERM and waits for in-flight requests to finish before the context closes. This prevents half-completed requests during rolling deployments. It is opt-in, so enable it explicitly. Shutdown sequence: 1. SIGTERM arrives (Kubernetes, systemd, Ctrl+C) 2. The server stops accepting new requests 3. Spring waits up to the timeout for active requests 4. Lifecycle callbacks run (@PreDestroy, ContextClosedEvent listeners) 5. The context closes and the JVM exits On Kubernetes, add a short preStop sleep (about 5 seconds) so the load balancer stops routing traffic first, and keep terminationGracePeriodSeconds longer than the Spring timeout.
application.properties
# application.properties
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s

Cleanup Hooks During Shutdown

Use `@PreDestroy` for simple resource cleanup. Use a `ContextClosedEvent` listener when you must act earlier, for example to drain a queue before connections close.
Java
@Component
public class QueueShutdownHandler {

    private static final Logger log = LoggerFactory.getLogger(QueueShutdownHandler.class);

    @EventListener(ContextClosedEvent.class)
    public void onShutdown() {
        log.info("Draining message queue...");
        queue.drain(Duration.ofSeconds(10));
    }

    @PreDestroy
    public void cleanup() {
        pool.close();
    }
}

7. Testing Support

Spring Boot lets you load only the layer under test, which keeps the suite fast. | Annotation | Loads | Use for | |---|---|---| | @SpringBootTest | Full context | End-to-end integration tests | | @WebMvcTest | MVC layer only | Controllers, validation, JSON | | @DataJpaTest | JPA layer + embedded DB | Repositories and queries | | @JsonTest | Serialization only | JSON mapping | `@MockBean` is deprecated from Boot 3.4 in favour of `@MockitoBean`. Use whichever matches your version.
Java
@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired private MockMvc mockMvc;

    @MockitoBean   // @MockBean on Boot < 3.4
    private UserService userService;

    @Test
    void getUser_returnsUser() throws Exception {
        when(userService.findById(1L))
            .thenReturn(Optional.of(new UserResponse(1L, "alice@test.com", "Alice")));

        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.email").value("alice@test.com"));
    }
}

8. Logging

Boot configures Logback through SLF4J by default, and levels, file output and rolling are set with properties. Production tips: - Keep the root level at INFO or WARN and raise only specific packages to DEBUG. - In containers, log to stdout and let the platform collect logs. - Use parameterized logging (`log.info("id={}", id)`), not string concatenation. - Boot 3.4+ supports structured JSON logging via `logging.structured.format.console=ecs`. - Avoid `org.hibernate.type` TRACE in production because it logs parameter values.
application.properties
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.logback.rollingpolicy.max-file-size=10MB
logging.logback.rollingpolicy.max-history=30
logging.file.name=logs/application.log

9. CLI and Spring Initializr

Spring Initializr (start.spring.io) generates a ready-to-run project with your build tool, Java version and dependencies. It's built into IntelliJ IDEA, VS Code and Spring Tools, and has an API you can script. Choose the Boot version in the Initializr UI rather than copying an old number from a tutorial. The Spring Boot CLI runs Groovy scripts without a build file. It suits quick prototypes, but use Initializr and Maven or Gradle for real applications.
Shell
curl https://start.spring.io/starter.zip \
  -d type=maven-project \
  -d language=java \
  -d javaVersion=21 \
  -d groupId=com.example \
  -d artifactId=myapp \
  -d dependencies=web,data-jpa,security,actuator,validation,devtools \
  -o myapp.zip

unzip myapp.zip -d myapp && cd myapp && ./mvnw spring-boot:run

How These Features Work Together in a Real Service

Individually each feature is simple. The value is in combining them. A typical production service uses all of these together: - Initializr and starters create the project and manage dependency versions. - Auto-configuration wires the database, web layer and security. - Profiles keep dev (H2, verbose logs) separate from prod (real database, quiet logs). - Externalized configuration injects secrets from the environment. - Actuator health probes tell Kubernetes when the app is live and ready. - Graceful shutdown plus a preStop hook gives zero-dropped-request deployments. - Slice tests keep CI fast. The configuration below shows several of these working together in one production profile.
yaml
# application-prod.yml
server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s
  datasource:
    url: ${DATABASE_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
  jpa:
    show-sql: false
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      probes:
        enabled: true
logging:
  level:
    root: WARN
    com.example: INFO

Which Feature Solves Which Problem?

- "My config differs per environment" → profiles and externalized configuration - "I need to know if the app is healthy" → Actuator health probes - "Requests fail during deployments" → graceful shutdown plus a Kubernetes preStop hook - "A bean isn't being created" → debug=true or /actuator/conditions - "Tests take too long" → slice tests instead of @SpringBootTest everywhere - "Restarts slow me down" → DevTools - "I need to change a log level in production" → Actuator loggers endpoint - "I want to start a new service quickly" → Spring Initializr

Common Mistakes With Spring Boot Features

- Exposing every Actuator endpoint in production. Expose only what you need. - Hardcoding secrets in application.properties. Use environment variables or a secrets manager. - Committing spring.profiles.active=prod. Set the profile per environment. - Using @SpringBootTest for everything. Slice tests are faster and more focused. - Excluding auto-configuration without understanding it. Inspect it first. - Copying outdated property names (for example server.tomcat.max-threads). Check your Boot version. - Skipping graceful shutdown, which drops in-flight requests during deployments.

Which Spring Boot Features Should You Learn First?

1. Starters and auto-configuration, to understand what Boot does for you 2. Externalized configuration and profiles, which every real project needs 3. Testing slices, to build good habits early 4. Actuator and logging, which production operations depend on 5. Graceful shutdown and the embedded server, for deployment and tuning 6. DevTools, CLI and Initializr, for productivity New to the framework? Start with What is Spring Boot and Spring Boot vs Spring, linked below.