# Spring Boot — User Guide

## 1. Quick Start

Spring Boot is a Java framework that makes it easy to create stand-alone, production-grade Spring-based applications. It provides opinionated defaults, embedded servers, and auto-configuration so you can focus on writing business logic instead of boilerplate infrastructure code.

**Key features:**

- **Auto-configuration** — automatically configures your application based on dependencies on the classpath
- **Embedded servers** — runs Tomcat, Jetty, or Netty directly inside your application JAR
- **Starter dependencies** — curated dependency sets that pull in everything needed for a feature
- **Production-ready features** — health checks, metrics, and externalized configuration via Actuator
- **Spring Boot CLI** — command-line tool for scaffolding and running Spring applications
- **Build plugins** — Gradle and Maven plugins for creating executable JARs/WARs and container images
- **Docker Compose support** — automatic service discovery and connection configuration from Docker Compose files
- **DevTools** — automatic restart, live reload, and development-time property defaults

**Prerequisites:**

- Java 17 or later (JDK)
- Maven 3.6.3+ or Gradle 7.6.4+

**Minimal application:**

```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class MyApplication {

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

    @GetMapping("/hello")
    public String hello() {
        return "Hello, World!";
    }
}
```

```bash
./mvnw spring-boot:run
```

```text
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

2026-05-07 10:00:00.123  INFO --- Started MyApplication in 2.345 seconds
```

Open `http://localhost:8080/hello` in a browser to see "Hello, World!".

> [!TIP]
> The fastest way to scaffold a new project is with [Spring Initializr](https://start.spring.io) — select your dependencies and download a ready-to-build project, or use `spring init` from the CLI.

**What to try next:** Add dependencies for web, data, or security starters, then let auto-configuration wire everything together. See the Installation section below to set up your environment, or jump to Core Usage for everyday tasks.

---

## 2. Installation

### System Requirements

| Requirement | Minimum Version |
|---|---|
| Java (JDK) | 17 |
| Maven | 3.6.3 |
| Gradle | 7.6.4 (8.x recommended) |
| Spring Framework | 6.2+ (managed automatically) |

### Project Setup with Spring Initializr

The recommended way to create a new Spring Boot project:

=== "Web (start.spring.io)"
    1. Navigate to [start.spring.io](https://start.spring.io)
    2. Select your project metadata (Group, Artifact, Java version)
    3. Add dependencies (e.g., Spring Web, Spring Data JPA)
    4. Click **Generate** to download the project ZIP
    5. Extract and open in your IDE

=== "Spring Boot CLI"
    ```bash
    spring init --dependencies=web,data-jpa,h2 my-project
    ```

=== "cURL"
    ```bash
    curl https://start.spring.io/starter.zip \
      -d dependencies=web,data-jpa \
      -d type=maven-project \
      -d language=java \
      -o my-project.zip
    ```

### Maven Setup

Add the Spring Boot parent POM to your `pom.xml`:

```xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.0</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
```

> [!IMPORTANT]
> The `spring-boot-starter-parent` manages dependency versions for the entire Spring ecosystem. If you cannot use a parent POM, import `spring-boot-dependencies` as a BOM in your `<dependencyManagement>` section instead.

### Gradle Setup

```groovy
plugins {
    id 'java'
    id 'org.springframework.boot' version '3.4.0'
    id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```

### Spring Boot CLI Installation

The Spring Boot CLI provides commands for project initialization, password encoding, and an interactive shell.

=== "SDKMAN! (Linux/macOS)"
    ```bash
    sdk install springboot
    ```

=== "Homebrew (macOS)"
    ```bash
    brew tap spring-io/tap
    brew install spring-boot
    ```

=== "Manual"
    Download the distribution from the Spring releases page, extract it, and add `bin/` to your `PATH`.

**Verify installation:**

```bash
spring version
```

```text
Spring CLI v3.4.0
```

### Post-Install Verification

**Maven:**

```bash
./mvnw spring-boot:run
```

**Gradle:**

```bash
./gradlew bootRun
```

Both should start the application with the Spring Boot banner and report the startup time. If no web starter is present, the application starts and exits immediately — that is expected for non-web applications.

> [!WARNING]
> If you see `Unsupported class file major version` errors, your JDK version is too old. Spring Boot requires JDK 17 or later. Run `java -version` to check.

### Install Troubleshooting

### Error: `Could not find artifact org.springframework.boot:spring-boot-starter-parent`

**Cause:** Maven cannot reach Maven Central or a corporate proxy is blocking downloads.

**Solution:**
1. Check your internet connection
2. Verify `~/.m2/settings.xml` proxy settings
3. Run `./mvnw -U spring-boot:run` to force snapshot updates

**Prevention:** Configure a local Maven mirror (Nexus, Artifactory) for reliable builds.

### Error: `Plugin 'org.springframework.boot' not found`

**Cause:** Gradle cannot resolve the Spring Boot plugin from the Gradle Plugin Portal.

**Solution:**
1. Check `settings.gradle` for `pluginManagement` blocks
2. Ensure `gradlePluginPortal()` is listed in plugin repositories
3. Run with `--refresh-dependencies`

**Prevention:** Pin plugin versions in `settings.gradle` `pluginManagement`.

### Error: `java.lang.UnsupportedClassVersionError`

**Cause:** The JDK version running the application is older than the version used to compile.

**Solution:**
1. Run `java -version` and `javac -version`
2. Ensure both are JDK 17+
3. Set `JAVA_HOME` to the correct JDK installation

**Prevention:** Use a Java version manager like SDKMAN! to manage JDK installations.

### Error: `Port 8080 already in use`

**Cause:** Another process is bound to the default HTTP port.

**Solution:**
1. Find the process: `lsof -i :8080` (Linux/macOS) or `netstat -ano | findstr :8080` (Windows)
2. Stop the conflicting process, or set a different port:
   ```properties
   server.port=8081
   ```

**Prevention:** Use `server.port=0` for random port assignment in tests and development.

### Error: `No auto configuration classes found in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`

**Cause:** The project structure doesn't match Spring Boot expectations, or the main class is in the wrong package.

**Solution:**
1. Ensure your `@SpringBootApplication` class is in a root package
2. Component scanning starts from the package of the main class downward
3. Move the main class to a parent package of all other classes

**Prevention:** Always place your main application class in a root package above other classes.

---

## 3. Configuration

Spring Boot uses a layered configuration system that loads properties from multiple sources in a defined order. Later sources override earlier ones.

### Configuration Files

Spring Boot loads configuration from `application.properties` or `application.yml` in the following locations (highest priority first):

1. Command-line arguments (`--server.port=9090`)
2. Java system properties (`-Dserver.port=9090`)
3. OS environment variables (`SERVER_PORT=9090`)
4. `application.properties` / `application.yml` in the current directory
5. `application.properties` / `application.yml` in `config/` subdirectory
6. `application.properties` / `application.yml` on the classpath (`src/main/resources/`)
7. Default values from auto-configuration

### Basic Configuration

```properties
# Server
server.port=8080
server.servlet.context-path=/api

# Logging
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.file.name=app.log

# Data Source
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=myuser
spring.datasource.password=secret

# JPA
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
```

### YAML Configuration

```yaml
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: myuser
    password: secret
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false

logging:
  level:
    root: INFO
    com.example: DEBUG
```

> [!NOTE]
> YAML and properties files are interchangeable. Use whichever format your team prefers. YAML supports hierarchical structure and list syntax natively; properties files are simpler for flat key-value pairs.

### Profiles

Profiles let you separate configuration by environment. Activate a profile with `spring.profiles.active`:

```properties
# application.properties (default)
spring.profiles.active=dev
```

```properties
# application-dev.properties
server.port=8080
spring.datasource.url=jdbc:h2:mem:devdb
logging.level.root=DEBUG
```

```properties
# application-prod.properties
server.port=443
spring.datasource.url=jdbc:postgresql://prod-db:5432/app
logging.level.root=WARN
```

Activate profiles via command line, environment variable, or JVM argument:

```bash
java -jar app.jar --spring.profiles.active=prod
```

```bash
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
```

> [!TIP]
> Use `spring.profiles.group` to combine multiple profiles into a single named group. For example, `spring.profiles.group.production=proddb,prodmq` activates both `proddb` and `prodmq` when `production` is active.

### Type-Safe Configuration Properties

Bind configuration properties to Java classes using `@ConfigurationProperties`:

```java
@ConfigurationProperties(prefix = "app.mail")
public class MailProperties {
    private String host;
    private int port = 25;
    private String username;

    // getters and setters
}
```

```properties
app.mail.host=smtp.example.com
app.mail.port=587
app.mail.username=noreply
```

Enable with `@EnableConfigurationProperties(MailProperties.class)` or `@ConfigurationPropertiesScan`.

### Environment Variables

Spring Boot automatically maps environment variables to properties using relaxed binding:

| Property | Environment Variable |
|---|---|
| `server.port` | `SERVER_PORT` |
| `spring.datasource.url` | `SPRING_DATASOURCE_URL` |
| `app.mail.host` | `APP_MAIL_HOST` |

Rules: uppercase, replace `.` with `_`, remove `-`.

> [!WARNING]
> Never commit sensitive values (passwords, API keys) in `application.properties`. Use environment variables, Spring Cloud Vault, or externalized secret management for production secrets.

For the full configuration reference with every property, default value, and type, see the Admin Guide.

---

## 4. Core Usage

### Creating a Web Application

#### REST Controllers

```java
@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public List<User> listUsers() {
        return userService.findAll();
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User createUser(@Valid @RequestBody User user) {
        return userService.save(user);
    }

    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}
```

#### Serving Static Content

Place static files in `src/main/resources/static/` or `src/main/resources/public/`. Spring Boot serves them automatically at the root URL path.

#### Template Engines

Spring Boot auto-configures Thymeleaf, FreeMarker, Mustache, and Groovy Templates when the appropriate starter is on the classpath. Place templates in `src/main/resources/templates/`.

```java
@Controller
public class HomeController {

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("message", "Welcome!");
        return "home"; // resolves to templates/home.html
    }
}
```

### Working with Data

#### Spring Data JPA

Add `spring-boot-starter-data-jpa` and a database driver:

```java
@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    // getters, setters
}

public interface CustomerRepository extends JpaRepository<Customer, Long> {
    List<Customer> findByName(String name);
    Optional<Customer> findByEmail(String email);
}
```

Spring Boot auto-configures the `DataSource`, `EntityManagerFactory`, and transaction manager based on your properties.

> [!NOTE]
> Spring Boot supports JPA, JDBC, R2DBC (reactive), MongoDB, Redis, Cassandra, Elasticsearch, Neo4j, Couchbase, and LDAP data stores through their respective starters. Each follows the same convention: add the starter, configure the connection, and define repositories.

#### Database Migrations

Spring Boot auto-runs Flyway or Liquibase migrations at startup when those dependencies are present:

```properties
# Flyway (default location: db/migration/)
spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration

# Liquibase
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.yaml
```

Place migration scripts in `src/main/resources/db/migration/`:

```sql
-- V1__Create_customer_table.sql
CREATE TABLE customer (
    id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE
);
```

### Security

Add `spring-boot-starter-security` and Spring Boot auto-configures:

- Form-based login at `/login`
- HTTP Basic authentication for API endpoints
- CSRF protection enabled
- A default user with username `user` and a generated password (printed at startup)

```text
Using generated security password: 8a2f4e9b-1234-5678-abcd-ef0123456789
```

Customize with a `SecurityFilterChain` bean:

```java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}
```

> [!IMPORTANT]
> The default generated password changes on every restart and is intended for development only. For production, configure a proper user store (JDBC, LDAP, or OAuth2 provider).

### Messaging

Spring Boot supports JMS (ActiveMQ, Artemis), AMQP (RabbitMQ), Kafka, Pulsar, and RSocket through starters.

**Kafka example:**

```java
@Component
public class OrderListener {

    @KafkaListener(topics = "orders")
    public void handleOrder(String message) {
        // process order
    }
}
```

```properties
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=order-service
spring.kafka.consumer.auto-offset-reset=earliest
```

### Reactive Applications with WebFlux

For non-blocking reactive applications, use `spring-boot-starter-webflux` instead of `spring-boot-starter-web`:

```java
@RestController
public class ReactiveController {

    @GetMapping("/flux")
    public Flux<String> flux() {
        return Flux.just("Hello", "Reactive", "World");
    }

    @GetMapping("/mono")
    public Mono<String> mono() {
        return Mono.just("Hello Reactive");
    }
}
```

WebFlux runs on Netty by default instead of Tomcat. Error handling follows the same `ErrorAttributes` pattern as MVC, with `DefaultErrorAttributes` providing timestamp, status, error, message, and path fields.

> [!WARNING]
> Do not add both `spring-boot-starter-web` and `spring-boot-starter-webflux` to the same project. Spring Boot defaults to MVC (Servlet) when both are present. Choose one paradigm per application.

### gRPC Support

Spring Boot includes built-in gRPC server and client support:

```properties
spring.grpc.server.port=9090
spring.grpc.client.my-service.address=static://localhost:9090
```

Define gRPC services by implementing the generated stubs and annotating with `@GrpcService`:

```java
@GrpcService
public class GreeterService extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloReply> observer) {
        HelloReply reply = HelloReply.newBuilder()
            .setMessage("Hello " + request.getName())
            .build();
        observer.onNext(reply);
        observer.onCompleted();
    }
}
```

### GraphQL

Add `spring-boot-starter-graphql` for GraphQL API support:

```java
@Controller
public class BookController {

    @QueryMapping
    public List<Book> books() {
        return bookService.findAll();
    }

    @MutationMapping
    public Book addBook(@Argument BookInput input) {
        return bookService.save(input);
    }
}
```

Place your schema in `src/main/resources/graphql/`:

```graphql
type Query {
    books: [Book]
}

type Book {
    id: ID!
    title: String!
    author: String!
}
```

---

## 5. Common Tasks

### Running Your Application

#### Development

```bash
# Maven
./mvnw spring-boot:run

# Gradle
./gradlew bootRun

# With arguments
./mvnw spring-boot:run -Dspring-boot.run.arguments="--server.port=9090"
```

#### Production

```bash
# Build executable JAR
./mvnw package
# or
./gradlew bootJar

# Run
java -jar target/my-app-0.0.1-SNAPSHOT.jar
```

> [!TIP]
> Use `java -jar app.jar --server.port=9090 --spring.profiles.active=prod` to override any configuration property at launch time.

### Building Executable JARs and WARs

Spring Boot creates self-contained JARs with embedded servers. The JAR contains your classes, all dependencies, and the embedded web server.

**Maven:**

```bash
./mvnw clean package
ls target/*.jar
```

```text
target/my-app-0.0.1-SNAPSHOT.jar
```

**Gradle:**

```bash
./gradlew bootJar
ls build/libs/*.jar
```

The resulting JAR is directly executable with `java -jar`.

**WAR packaging** (for external servlet containers):

```xml
<packaging>war</packaging>
```

```groovy
apply plugin: 'war'
```

### Building Container Images

Spring Boot builds OCI container images directly from your application using Cloud Native Buildpacks — no Dockerfile required:

**Maven:**

```bash
./mvnw spring-boot:build-image
```

**Gradle:**

```bash
./gradlew bootBuildImage
```

```text
Successfully built image 'docker.io/library/my-app:0.0.1-SNAPSHOT'
```

Customize the image:

```groovy
bootBuildImage {
    imageName = "example.com/myapp:${version}"
    builder = "paketobuildpacks/builder-jammy-base:latest"
    pullPolicy = "IF_NOT_PRESENT"
    environment = [
        "BP_JVM_VERSION": "17",
        "BP_LIVE_RELOAD_ENABLED": "true"
    ]
    tags = ["example.com/myapp:latest"]
}
```

Command-line options for `bootBuildImage`:

| Option | Description |
|---|---|
| `--imageName` | Custom image name |
| `--builder` | Builder image to use |
| `--runImage` | Run image for the final layer |
| `--pullPolicy` | `ALWAYS`, `NEVER`, `IF_NOT_PRESENT` |
| `--trustBuilder` | Trust the builder (runs in single-phase mode) |
| `--createdDate` | Set image creation date |
| `--applicationDirectory` | Application directory in the image |
| `--environment` | Environment variables for the build |

### Using DevTools

Add `spring-boot-devtools` for an enhanced development experience:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
```

**Features:**
- **Automatic restart** — the application restarts when classpath files change
- **LiveReload** — browser automatically refreshes when resources change
- **Property defaults** — development-friendly defaults (e.g., caching disabled)
- **Remote debugging** — support for remote development against running applications

Configure restart behavior in `META-INF/spring-devtools.properties`:

```properties
restart.include.my-library=/my-library-[\w\d-\.]+\.jar
restart.exclude.my-static=/my-static-[\w\d-\.]+\.jar
```

> [!NOTE]
> DevTools is automatically disabled when running a fully packaged application (`java -jar`). It only activates when launched from an IDE or with `spring-boot:run`. The build plugins exclude it from production JARs.

### Using Docker Compose

Spring Boot automatically detects and manages Docker Compose services during development. Add `spring-boot-docker-compose`:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-docker-compose</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
```

With a `compose.yaml` in your project root:

```yaml
services:
  postgres:
    image: postgres:16
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: secret
  redis:
    image: redis:7
    ports:
      - "6379:6379"
```

Spring Boot will:
1. Detect the compose file at startup
2. Run `docker compose up` if services are not already running
3. Discover service ports (including ephemeral port mapping)
4. Auto-configure `DataSource`, `RedisConnectionFactory`, etc. from the running containers
5. Optionally run `docker compose down` on shutdown

### Monitoring with Actuator

Add `spring-boot-starter-actuator` for production monitoring endpoints:

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
```

```properties
# Expose all endpoints over HTTP
management.endpoints.web.exposure.include=health,info,metrics,env,loggers

# Show full health details
management.endpoint.health.show-details=always
```

**Key endpoints:**

| Endpoint | Description |
|---|---|
| `/actuator/health` | Application health status (UP/DOWN) |
| `/actuator/info` | Application metadata |
| `/actuator/metrics` | Application metrics (JVM, HTTP, custom) |
| `/actuator/env` | Environment properties |
| `/actuator/loggers` | View and change log levels at runtime |
| `/actuator/httptrace` | Recent HTTP request/response trace |
| `/actuator/beans` | All registered Spring beans |
| `/actuator/conditions` | Auto-configuration evaluation report |

```bash
curl http://localhost:8080/actuator/health
```

```json
{
  "status": "UP",
  "components": {
    "db": { "status": "UP" },
    "diskSpace": { "status": "UP" }
  }
}
```

> [!WARNING]
> In production, restrict Actuator endpoint exposure. Use `management.endpoints.web.exposure.include` to expose only what is needed, and secure endpoints with Spring Security. Some endpoints (like `env` and `beans`) reveal sensitive configuration details.

### Testing

Spring Boot provides comprehensive testing support through `spring-boot-starter-test`:

```java
@SpringBootTest
class MyApplicationTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldReturnHello() throws Exception {
        mockMvc.perform(get("/hello"))
            .andExpect(status().isOk())
            .andExpect(content().string("Hello, World!"));
    }
}
```

**Test slice annotations** for focused testing:

| Annotation | Scope |
|---|---|
| `@WebMvcTest` | MVC controllers only |
| `@WebFluxTest` | WebFlux controllers only |
| `@DataJpaTest` | JPA repositories with in-memory DB |
| `@JsonTest` | JSON serialization/deserialization |
| `@RestClientTest` | REST client with mock server |

```java
@WebMvcTest(UserController.class)
class UserControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @MockitoBean
    private UserService userService;

    @Test
    void shouldListUsers() throws Exception {
        when(userService.findAll()).thenReturn(List.of(new User("Alice")));
        mockMvc.perform(get("/api/users"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$[0].name").value("Alice"));
    }
}
```

### Testcontainers Integration

Spring Boot integrates with Testcontainers for integration tests against real databases and services:

```java
@SpringBootTest
@Testcontainers
class IntegrationTests {

    @Container
    @ServiceConnection
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");

    @Test
    void shouldConnectToDatabase(@Autowired DataSource dataSource) {
        assertThat(dataSource.getConnection()).isNotNull();
    }
}
```

The `@ServiceConnection` annotation automatically configures the data source connection from the container.

### Structured Logging

Spring Boot supports structured logging output for integration with log aggregation systems:

```properties
# JSON-formatted log output
logging.structured.format.console=ecs
logging.structured.format.file=logstash
```

Supported formats include ECS (Elastic Common Schema) and Logstash JSON.

### Password Encoding (CLI)

The Spring Boot CLI provides a password encoding utility:

```bash
spring encodepassword mypassword
```

```text
{bcrypt}$2a$10$...
```

This generates a BCrypt-encoded password suitable for use in Spring Security configuration.

### Using Starters

Starters are curated dependency descriptors. Add a single starter instead of tracking individual library versions:

| Starter | Purpose |
|---|---|
| `spring-boot-starter-web` | Web applications (Tomcat, Spring MVC) |
| `spring-boot-starter-webflux` | Reactive web (Netty, WebFlux) |
| `spring-boot-starter-data-jpa` | JPA with Hibernate |
| `spring-boot-starter-data-mongodb` | MongoDB |
| `spring-boot-starter-data-redis` | Redis |
| `spring-boot-starter-security` | Spring Security |
| `spring-boot-starter-actuator` | Production monitoring |
| `spring-boot-starter-test` | Testing (JUnit, Mockito, AssertJ) |
| `spring-boot-starter-validation` | Bean Validation (Hibernate Validator) |
| `spring-boot-starter-cache` | Caching abstraction |
| `spring-boot-starter-amqp` | RabbitMQ |
| `spring-boot-starter-mail` | Email sending |
| `spring-boot-starter-batch` | Spring Batch |
| `spring-boot-starter-quartz` | Quartz Scheduler |
| `spring-boot-starter-websocket` | WebSocket support |
| `spring-boot-starter-graphql` | GraphQL API |
| `spring-boot-starter-hateoas` | HATEOAS REST APIs |
| `spring-boot-starter-oauth2-resource-server` | OAuth2 resource server |
| `spring-boot-starter-rsocket` | RSocket messaging |

### Observability with Micrometer and OpenTelemetry

Spring Boot auto-configures Micrometer metrics and tracing:

```properties
# Prometheus metrics export
management.prometheus.metrics.export.enabled=true

# Distributed tracing
management.tracing.sampling.probability=1.0

# OpenTelemetry
management.otlp.tracing.endpoint=http://localhost:4318/v1/traces
management.otlp.metrics.export.url=http://localhost:4318/v1/metrics
```

Custom metrics:

```java
@Component
public class OrderMetrics {

    private final Counter ordersPlaced;

    public OrderMetrics(MeterRegistry registry) {
        this.ordersPlaced = registry.counter("orders.placed");
    }

    public void recordOrder() {
        ordersPlaced.increment();
    }
}
```

---

## 6. Troubleshooting

### Diagnostic Decision Tree

```text
Application won't start?
├── Port conflict? → Check server.port, kill conflicting process
├── Bean creation failure? → Check dependency injection, missing beans
├── Database connection? → Verify connection URL, credentials, driver
├── Class not found? → Check dependencies, classpath
└── Configuration error? → Validate property names, types, profiles

Application starts but behaves unexpectedly?
├── Wrong profile active? → Check spring.profiles.active
├── Properties not loading? → Check file location, property name spelling
├── Auto-config not applying? → Run with --debug, check /actuator/conditions
└── Security blocking requests? → Check SecurityFilterChain, CSRF settings
```

### Error: `BeanCurrentlyInCreationException: Error creating bean`

**Cause:** Circular dependency between beans — Bean A requires Bean B, which requires Bean A.

**Solution:**
1. Redesign to break the cycle (extract shared logic into a third bean)
2. Use `@Lazy` on one of the injection points as a temporary workaround
3. Use setter injection instead of constructor injection for one side

**Prevention:** Follow the dependency inversion principle. Keep the dependency graph acyclic.

### Error: `DataSource: Failed to determine suitable driver class`

**Cause:** Spring Boot detected a data-related dependency but cannot find a JDBC driver on the classpath.

**Solution:**
1. Add the appropriate database driver dependency (e.g., `postgresql`, `mysql-connector-j`, `h2`)
2. If you don't need a database, exclude `DataSourceAutoConfiguration`:
   ```java
   @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
   ```

**Prevention:** Only include data starters when you actually need database access.

### Error: `WebMvcTest fails with NPE while evaluating controller method default argument`

**Cause:** A known issue when `@WebMvcTest` encounters controller methods with default parameter values in Kotlin or certain Java patterns. (Community issue #49859)

**Solution:**
1. Provide explicit values in test request parameters
2. Avoid default method arguments in controller methods used with `@WebMvcTest`

**Prevention:** Use explicit parameter binding with `@RequestParam(required = false, defaultValue = "...")`.

### Error: `Slf4JBridgeHandler.uninstall called too early in context close`

**Cause:** During application shutdown, the SLF4J bridge handler is removed before all JUL (java.util.logging) log output has been flushed, swallowing late shutdown messages. (Community issue #33697)

**Solution:**
1. If you need to see JUL output during shutdown, add a custom `DisposableBean` that delays handler removal
2. Use SLF4J-native loggers throughout your application to avoid the bridge

**Prevention:** Prefer SLF4J/Logback for all logging to avoid JUL bridge timing issues.

### Error: `Spring Boot CLI shows configurationFileFormat option which is not available`

**Cause:** The CLI's `spring init` command displays the `configurationFileFormat` option in help, but the option is not functional when creating projects. (Community issue #49960)

**Solution:** Ignore this option. Use `--type` to specify Maven/Gradle and `--language` for Java/Kotlin/Groovy instead.

**Prevention:** This is a known CLI cosmetic issue.

### Error: `Tomcat connector failure with HTTPS and virtual threads`

**Cause:** Misconfiguration when combining embedded Tomcat HTTPS with virtual threads.

**Solution:**
1. Verify your SSL keystore configuration:
   ```properties
   server.ssl.key-store=classpath:keystore.p12
   server.ssl.key-store-password=changeit
   server.ssl.key-store-type=PKCS12
   ```
2. Ensure your JDK supports virtual threads (Java 21+) when using `spring.threads.virtual.enabled=true`

**Prevention:** Test HTTPS and virtual thread configurations together before deploying.

### Error: `ApplicationPidFileWriter does not handle symlinks correctly`

**Cause:** When the PID file path involves symbolic links, the writer may fail to create or update the file. (Community issue #50186)

**Solution:**
1. Use a direct path (no symlinks) for the PID file location:
   ```properties
   spring.pid.file=/var/run/myapp.pid
   ```
2. Ensure the target directory of the symlink exists and is writable

**Prevention:** Avoid symlinked paths for PID file locations.

### Error: `RandomValuePropertySource is not suitable for secrets`

**Cause:** Using `${random.value}` or `${random.uuid}` in properties for secrets generates new values on every restart and is not cryptographically secure. (Community issue #50184)

**Solution:** Use a proper secret management system (environment variables, Vault, Kubernetes secrets) instead of random property sources for sensitive values.

**Prevention:** Never use `random.*` property sources for passwords, tokens, or keys.

### Error: `Cassandra auto-configuration misconfigures CqlSessionBuilder`

**Cause:** Auto-configuration may apply incorrect default settings for Cassandra connections in certain configurations. (Community issue #50182)

**Solution:**
1. Explicitly configure the `CqlSessionBuilder` bean
2. Override the auto-configured properties:
   ```properties
   spring.cassandra.contact-points=localhost
   spring.cassandra.port=9042
   spring.cassandra.local-datacenter=datacenter1
   ```

**Prevention:** Always specify `spring.cassandra.local-datacenter` explicitly.

> [!CAUTION]
> When troubleshooting auto-configuration issues, run your application with `--debug` or set `debug=true` in properties. This prints a comprehensive conditions evaluation report showing which auto-configurations were applied and which were skipped, and why.

---

## 7. FAQ

**Q: How do I change the default port?**

Set `server.port` in `application.properties`, via environment variable `SERVER_PORT`, or command-line argument `--server.port=9090`. Use `server.port=0` for a random available port.

**Q: How do I create a non-web application?**

Don't include any web starter. Implement `CommandLineRunner` or `ApplicationRunner` for startup logic:

```java
@SpringBootApplication
public class BatchApp implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(BatchApp.class, args);
    }

    @Override
    public void run(String... args) {
        // your batch logic
    }
}
```

**Q: How do I use multiple data sources?**

Define each `DataSource` as a `@Bean` with `@ConfigurationProperties` pointing to different property prefixes. Mark one as `@Primary`. See the Admin Guide for a complete multi-datasource configuration example.

**Q: Can I use Spring Boot with Kotlin?**

Yes. Spring Boot has first-class Kotlin support. Use the `kotlin-spring` compiler plugin (for open classes) and `kotlin-jpa` (for no-arg constructors). All documentation examples are available in both Java and Kotlin.

**Q: How do I disable a specific auto-configuration?**

Use the `exclude` attribute on `@SpringBootApplication`:

```java
@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class,
    SecurityAutoConfiguration.class
})
```

Or set `spring.autoconfigure.exclude` in properties.

**Q: How do I serve my application behind a reverse proxy?**

Configure `server.forward-headers-strategy=native` or `framework` to handle `X-Forwarded-*` headers:

```properties
server.forward-headers-strategy=framework
server.tomcat.remoteip.remote-ip-header=X-Forwarded-For
server.tomcat.remoteip.protocol-header=X-Forwarded-Proto
```

**Q: How do I enable HTTPS?**

```properties
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
server.ssl.enabled=true
```

**Q: How do I externalize configuration for Docker/Kubernetes?**

Use environment variables (Spring Boot maps them automatically) or mount configuration files. In Kubernetes, use ConfigMaps and Secrets:

```yaml
env:
  - name: SPRING_DATASOURCE_URL
    value: jdbc:postgresql://db:5432/mydb
  - name: SPRING_PROFILES_ACTIVE
    value: prod
```

**Q: How does auto-configuration work?**

Spring Boot scans `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` for auto-configuration classes. Each class uses `@Conditional` annotations to check whether its requirements are met (class on classpath, bean not already defined, property set, etc.). If conditions pass, the auto-configuration creates and configures beans automatically.

**Q: How do I create a custom starter?**

Create two modules: an `autoconfigure` module (with `@AutoConfiguration` class and `META-INF/spring/...imports` registration) and a `starter` module (which depends on `autoconfigure` and pulls in required libraries). See the Admin Guide for the complete starter development pattern.

**Q: How do I handle validation errors in REST APIs?**

With `spring-boot-starter-validation`, annotate request bodies with `@Valid`. Spring Boot returns 400 Bad Request with error details:

```java
@PostMapping("/users")
public User create(@Valid @RequestBody User user) { ... }
```

Customize error responses by implementing `ErrorAttributes` or using `@ExceptionHandler`.

**Q: What is the difference between `@Component`, `@Service`, `@Repository`, and `@Controller`?**

They are all specializations of `@Component` and mark classes for component scanning. `@Service` indicates a business logic class, `@Repository` a data access class (with automatic exception translation), and `@Controller` / `@RestController` an MVC controller. Functionally they behave the same for dependency injection — the distinction is semantic.

> [!TIP]
> Run your application with `--debug` to see a comprehensive auto-configuration report showing exactly which auto-configurations matched or failed, and why.

---

_Generated May 2026 from spring-projects/spring-boot at b9ee76e. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
