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:
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!";
}
}
./mvnw spring-boot:run
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
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 — select your dependencies and download a ready-to-build project, or use
spring initfrom 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)
- Navigate to start.spring.io
- Select your project metadata (Group, Artifact, Java version)
- Add dependencies (e.g., Spring Web, Spring Data JPA)
- Click Generate to download the project ZIP
- Extract and open in your IDE
Spring Boot CLI
spring init --dependencies=web,data-jpa,h2 my-project
cURL
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:
<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-parentmanages dependency versions for the entire Spring ecosystem. If you cannot use a parent POM, importspring-boot-dependenciesas a BOM in your<dependencyManagement>section instead.
Gradle Setup
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)
sdk install springboot
Homebrew (macOS)
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:
spring version
Spring CLI v3.4.0
Post-Install Verification
Maven:
./mvnw spring-boot:run
Gradle:
./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 versionerrors, your JDK version is too old. Spring Boot requires JDK 17 or later. Runjava -versionto 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:
- Check your internet connection
- Verify
~/.m2/settings.xmlproxy settings - Run
./mvnw -U spring-boot:runto 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:
- Check
settings.gradleforpluginManagementblocks - Ensure
gradlePluginPortal()is listed in plugin repositories - 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:
- Run
java -versionandjavac -version - Ensure both are JDK 17+
- Set
JAVA_HOMEto 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:
- Find the process:
lsof -i :8080(Linux/macOS) ornetstat -ano | findstr :8080(Windows) - Stop the conflicting process, or set a different port:
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:
- Ensure your
@SpringBootApplicationclass is in a root package - Component scanning starts from the package of the main class downward
- 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):
- Command-line arguments (
--server.port=9090) - Java system properties (
-Dserver.port=9090) - OS environment variables (
SERVER_PORT=9090) application.properties/application.ymlin the current directoryapplication.properties/application.ymlinconfig/subdirectoryapplication.properties/application.ymlon the classpath (src/main/resources/)- Default values from auto-configuration
Basic Configuration
# 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
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:
# application.properties (default)
spring.profiles.active=dev
# application-dev.properties
server.port=8080
spring.datasource.url=jdbc:h2:mem:devdb
logging.level.root=DEBUG
# 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:
java -jar app.jar --spring.profiles.active=prod
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
Tip
Use
spring.profiles.groupto combine multiple profiles into a single named group. For example,spring.profiles.group.production=proddb,prodmqactivates bothproddbandprodmqwhenproductionis active.
Type-Safe Configuration Properties
Bind configuration properties to Java classes using @ConfigurationProperties:
@ConfigurationProperties(prefix = "app.mail")
public class MailProperties {
private String host;
private int port = 25;
private String username;
// getters and setters
}
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
@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/.
@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:
@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:
# 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/:
-- 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
userand a generated password (printed at startup)
Using generated security password: 8a2f4e9b-1234-5678-abcd-ef0123456789
Customize with a SecurityFilterChain bean:
@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:
@Component
public class OrderListener {
@KafkaListener(topics = "orders")
public void handleOrder(String message) {
// process order
}
}
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:
@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-webandspring-boot-starter-webfluxto 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:
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:
@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:
@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/:
type Query {
books: [Book]
}
type Book {
id: ID!
title: String!
author: String!
}
5. Common Tasks
Running Your Application
Development
# Maven
./mvnw spring-boot:run
# Gradle
./gradlew bootRun
# With arguments
./mvnw spring-boot:run -Dspring-boot.run.arguments="--server.port=9090"
Production
# 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=prodto 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:
./mvnw clean package
ls target/*.jar
target/my-app-0.0.1-SNAPSHOT.jar
Gradle:
./gradlew bootJar
ls build/libs/*.jar
The resulting JAR is directly executable with java -jar.
WAR packaging (for external servlet containers):
<packaging>war</packaging>
apply plugin: 'war'
Building Container Images
Spring Boot builds OCI container images directly from your application using Cloud Native Buildpacks — no Dockerfile required:
Maven:
./mvnw spring-boot:build-image
Gradle:
./gradlew bootBuildImage
Successfully built image 'docker.io/library/my-app:0.0.1-SNAPSHOT'
Customize the image:
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:
<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:
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 withspring-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:
<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:
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:
- Detect the compose file at startup
- Run
docker compose upif services are not already running - Discover service ports (including ephemeral port mapping)
- Auto-configure
DataSource,RedisConnectionFactory, etc. from the running containers - Optionally run
docker compose downon shutdown
Monitoring with Actuator
Add spring-boot-starter-actuator for production monitoring endpoints:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# 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 |
curl http://localhost:8080/actuator/health
{
"status": "UP",
"components": {
"db": { "status": "UP" },
"diskSpace": { "status": "UP" }
}
}
Warning
In production, restrict Actuator endpoint exposure. Use
management.endpoints.web.exposure.includeto expose only what is needed, and secure endpoints with Spring Security. Some endpoints (likeenvandbeans) reveal sensitive configuration details.
Testing
Spring Boot provides comprehensive testing support through spring-boot-starter-test:
@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 |
@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:
@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:
# 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:
spring encodepassword mypassword
{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:
# 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:
@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
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:
- Redesign to break the cycle (extract shared logic into a third bean)
- Use
@Lazyon one of the injection points as a temporary workaround - 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:
- Add the appropriate database driver dependency (e.g.,
postgresql,mysql-connector-j,h2) - If you don't need a database, exclude
DataSourceAutoConfiguration:@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:
- Provide explicit values in test request parameters
- 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:
- If you need to see JUL output during shutdown, add a custom
DisposableBeanthat delays handler removal - 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:
- Verify your SSL keystore configuration:
server.ssl.key-store=classpath:keystore.p12 server.ssl.key-store-password=changeit server.ssl.key-store-type=PKCS12 - 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:
- Use a direct path (no symlinks) for the PID file location:
spring.pid.file=/var/run/myapp.pid - 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:
- Explicitly configure the
CqlSessionBuilderbean - Override the auto-configured 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
--debugor setdebug=truein 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:
@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:
@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:
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?
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:
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:
@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
--debugto see a comprehensive auto-configuration report showing exactly which auto-configurations matched or failed, and why.