1. Architecture Overview
Spring Boot is a convention-over-configuration framework built on top of the Spring Framework. It eliminates boilerplate setup by providing auto-configuration, embedded servers, and opinionated defaults while preserving the full power and flexibility of the Spring ecosystem. The framework is designed as a multi-module Gradle project (11,264 source files, ~15M characters of source code) organized around a layered architecture that separates core runtime, auto-configuration, build tooling, and operational features.
The fundamental design principle is auto-configuration through classpath detection: Spring Boot scans the classpath for known libraries, evaluates conditional annotations (@ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty), and automatically creates and configures infrastructure beans. This allows applications to work with zero explicit configuration while remaining fully customizable when needed.
Spring Boot also introduces the concept of executable JARs — self-contained archives that embed all dependencies and an application server (Tomcat, Jetty, or Netty), enabling java -jar deployment without external servlet containers.
System Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Application Code │
│ (@SpringBootApplication, Controllers, Services, Repositories) │
├─────────────────────────────────────────────────────────────────┤
│ Spring Boot Modules │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ WebMVC │ │ WebFlux │ │ Data JPA │ │ Security │ │
│ │ Module │ │ Module │ │ Module │ │ Module │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Actuator │ │ DevTools │ │ Docker │ │ Messaging │ │
│ │ Module │ │ Module │ │ Compose │ │ (Kafka/AMQP/JMS) │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Core & Auto-Configure │
│ ┌─────────────────┐ ┌─────────────────────────────────────┐ │
│ │ spring-boot │ │ spring-boot-autoconfigure │ │
│ │ (SpringApp, │ │ (conditional bean creation, │ │
│ │ ConfigData, │ │ property binding, classpath │ │
│ │ Loader) │ │ detection) │ │
│ └─────────────────┘ └─────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Spring Framework 6.2+ │
│ (IoC Container, AOP, Transaction Management, MVC, WebFlux) │
├─────────────────────────────────────────────────────────────────┤
│ JVM (Java 17+) │
└─────────────────────────────────────────────────────────────────┘
Note
Spring Boot modules are designed as independently consumable units. An application only loads the modules whose starters are on the classpath. The auto-configure layer acts as the glue — it detects which modules are present and wires them together.
Component Inventory
| Component | Path | Role |
|---|---|---|
core/spring-boot |
Core runtime | SpringApplication, configuration loading, embedded server abstraction, banner, logging |
core/spring-boot-autoconfigure |
Auto-configuration engine | Conditional bean definitions for 100+ technologies |
core/spring-boot-autoconfigure-processor |
Compile-time processor | Generates metadata for auto-configuration conditions |
core/spring-boot-test |
Testing support | @SpringBootTest, mock environments, output capture |
core/spring-boot-test-autoconfigure |
Test slices | @WebMvcTest, @DataJpaTest, @JsonTest, etc. |
core/spring-boot-docker-compose |
Docker Compose integration | Auto-start/stop containers, port discovery, service connections |
core/spring-boot-properties-migrator |
Property migration | Detects deprecated properties and suggests replacements |
module/spring-boot-actuator |
Actuator core | Health, metrics, audit, info endpoint implementations |
module/spring-boot-actuator-autoconfigure |
Actuator auto-config | Conditional configuration of actuator features |
module/spring-boot-webmvc |
Spring MVC integration | Error handling, auto-configuration for MVC |
module/spring-boot-webflux |
WebFlux integration | Reactive error handling, Netty auto-configuration |
module/spring-boot-devtools |
Developer tools | Auto-restart, LiveReload, remote debugging |
module/spring-boot-health |
Health system | HealthContributor registry, health aggregation |
module/spring-boot-security |
Security integration | OAuth2, SAML2, OIDC auto-configuration |
module/spring-boot-jackson |
Jackson integration | ObjectMapper auto-configuration, JSON serialization |
module/spring-boot-jpa |
JPA/Hibernate | Entity manager, repository, DDL auto-configuration |
module/spring-boot-web-server |
Embedded servers | Tomcat, Jetty, Netty, Undertow factories |
module/spring-boot-grpc-server |
gRPC support | gRPC server auto-configuration |
module/spring-boot-grpc-client |
gRPC client | gRPC client auto-configuration |
module/spring-boot-micrometer-metrics |
Metrics | Micrometer integration, meter registries |
module/spring-boot-micrometer-tracing |
Distributed tracing | Micrometer Tracing, Brave/OTel integration |
module/spring-boot-opentelemetry |
OpenTelemetry | OTLP export, OTel SDK auto-configuration |
loader/spring-boot-loader |
Executable JAR loader | Nested JAR support, custom classloader |
loader/spring-boot-loader-tools |
Loader build tools | JAR/WAR repackaging, layer extraction |
loader/spring-boot-jarmode-tools |
JAR mode tools | Layer listing and extraction for Docker builds |
cli/spring-boot-cli |
Command-line interface | Project init, password encoding, shell |
build-plugin/spring-boot-gradle-plugin |
Gradle plugin | bootJar, bootWar, bootRun, bootBuildImage tasks |
build-plugin/spring-boot-maven-plugin |
Maven plugin | spring-boot:run, spring-boot:build-image, repackage goals |
build-plugin/spring-boot-antlib |
Ant support | Ant task library for Spring Boot builds |
buildpack/spring-boot-buildpack-platform |
Buildpack platform | Docker API, CNB lifecycle, image building |
platform/spring-boot-dependencies |
BOM | Managed dependency versions for the ecosystem |
starter/* |
Starters | Curated dependency sets (~60 starters) |
configuration-metadata/* |
Config metadata | Changelog generator for configuration property changes |
Technology Stack
| Layer | Technology |
|---|---|
| Language | Java 17+ (Kotlin and Groovy supported) |
| Build | Gradle (primary), Maven, Ant |
| Core Framework | Spring Framework 6.2+ |
| Servlet Containers | Tomcat (default), Jetty, Undertow |
| Reactive Runtime | Netty (default for WebFlux) |
| Persistence | Hibernate/JPA, Spring Data, JDBC, R2DBC |
| Security | Spring Security 6.x |
| Messaging | Kafka, RabbitMQ (AMQP), ActiveMQ, Artemis (JMS), Pulsar, RSocket |
| Observability | Micrometer, OpenTelemetry, Prometheus |
| Testing | JUnit 5, Mockito, AssertJ, Testcontainers |
| Documentation | Antora (AsciiDoc-based site generator) |
| Container Images | Cloud Native Buildpacks (CNB), Docker API |
Application Lifecycle
main() → SpringApplication.run()
│
├── 1. Create SpringApplication instance
├── 2. Publish ApplicationStartingEvent
├── 3. Prepare Environment (load application.properties/yml, profiles)
├── 4. Publish ApplicationEnvironmentPreparedEvent
├── 5. Create ApplicationContext
├── 6. Publish ApplicationContextInitializedEvent
├── 7. Load bean definitions (component scan, auto-configuration)
├── 8. Publish ApplicationPreparedEvent
├── 9. Refresh context (instantiate beans, start embedded server)
├── 10. Publish ApplicationStartedEvent
├── 11. Call ApplicationRunner / CommandLineRunner beans
├── 12. Publish ApplicationReadyEvent
│
└── Running (serving requests)
│
└── Shutdown
├── Publish ContextClosedEvent
├── Stop embedded server (graceful shutdown)
└── Destroy beans
Important
The
ApplicationFailedEventis published if startup fails at any stage. Register listeners for this event to implement custom error reporting, cleanup, or alerting on startup failures.
Data Flow — HTTP Request Processing
HTTP Request
│
├── Embedded Server (Tomcat/Jetty/Netty)
│ └── Servlet Filter Chain / WebFilter Chain
│ ├── Security Filters (authentication, authorization)
│ ├── Error Handling (ErrorController / ErrorWebExceptionHandler)
│ └── DispatcherServlet / DispatcherHandler
│ ├── Handler Mapping (URL → Controller method)
│ ├── Handler Adapter (invoke method)
│ ├── Argument Resolution (@RequestBody, @PathVariable)
│ ├── Return Value Handling (JSON serialization)
│ └── Exception Resolution (ErrorAttributes)
│
└── HTTP Response
2. System Requirements
Runtime Requirements
| Requirement | Specification |
|---|---|
| Java | JDK 17, 21, or later LTS releases |
| Spring Framework | 6.2+ (managed by Spring Boot BOM) |
| Memory | Minimum 256 MB heap, recommended 512 MB+ for web applications |
| Disk | ~50 MB for the framework + application size |
Build Requirements
| Tool | Minimum Version | Recommended |
|---|---|---|
| Gradle | 7.6.4 | 8.x |
| Maven | 3.6.3 | 3.9.x |
| JDK (build) | 17 | 21 |
Supported Embedded Servers
| Server | Module | Type |
|---|---|---|
| Apache Tomcat | spring-boot-starter-tomcat (default) |
Servlet |
| Eclipse Jetty | spring-boot-starter-jetty |
Servlet |
| Undertow | spring-boot-starter-undertow |
Servlet |
| Netty | spring-boot-starter-webflux (default) |
Reactive |
Supported Databases
| Database | Driver Starter | Notes |
|---|---|---|
| H2 | com.h2database:h2 |
In-memory, dev/test |
| PostgreSQL | org.postgresql:postgresql |
Production |
| MySQL/MariaDB | com.mysql:mysql-connector-j |
Production |
| Oracle | com.oracle.database.jdbc:ojdbc11 |
Production |
| SQL Server | com.microsoft.sqlserver:mssql-jdbc |
Production |
| MongoDB | spring-boot-starter-data-mongodb |
NoSQL |
| Redis | spring-boot-starter-data-redis |
Cache/Store |
| Cassandra | spring-boot-starter-data-cassandra |
NoSQL |
| Elasticsearch | spring-boot-starter-data-elasticsearch |
Search |
| Neo4j | spring-boot-starter-data-neo4j |
Graph |
| Couchbase | spring-boot-starter-data-couchbase |
NoSQL |
3. Configuration Reference
Configuration File Locations and Priority
Spring Boot loads configuration from multiple sources. Later sources override earlier ones:
| Priority | Source | Example |
|---|---|---|
| 1 (highest) | Command-line arguments | --server.port=9090 |
| 2 | SPRING_APPLICATION_JSON |
Inline JSON in env var |
| 3 | Servlet init parameters | Web container config |
| 4 | JNDI attributes | java:comp/env/ |
| 5 | Java system properties | -Dserver.port=9090 |
| 6 | OS environment variables | SERVER_PORT=9090 |
| 7 | Random value properties | ${random.int} |
| 8 | Profile-specific external | ./config/application-prod.properties |
| 9 | Profile-specific classpath | classpath:/application-prod.properties |
| 10 | Application external | ./config/application.properties |
| 11 | Application classpath | classpath:/application.properties |
| 12 (lowest) | @PropertySource annotations |
On @Configuration classes |
Configuration File Search Locations
Files are searched in this order (first found wins within each priority level):
file:./config/— aconfig/directory in the current working directoryfile:./config/*/— immediate subdirectories ofconfig/file:./— current working directoryclasspath:/config/— config package on the classpathclasspath:/— root of the classpath
Important
Profile-specific files (
application-{profile}.properties) always override non-profile-specific files, regardless of location. A profile-specific file inside the JAR overrides a non-profile-specific file outside the JAR.
Core Server Properties
| Property | Type | Default | Description |
|---|---|---|---|
server.port |
Integer | 8080 |
HTTP port |
server.address |
String | 0.0.0.0 |
Network interface to bind |
server.servlet.context-path |
String | / |
Application context path |
server.servlet.session.timeout |
Duration | 30m |
Session timeout |
server.shutdown |
String | immediate |
Shutdown mode (immediate or graceful) |
server.error.include-message |
String | never |
Include message in error responses |
server.error.include-stacktrace |
String | never |
Include stacktrace in error responses |
server.error.include-binding-errors |
String | never |
Include binding errors |
server.forward-headers-strategy |
String | none |
none, native, framework |
server.compression.enabled |
Boolean | false |
Enable response compression |
server.compression.mime-types |
List | text/html,... |
MIME types to compress |
SSL/TLS Properties
| Property | Type | Default | Description |
|---|---|---|---|
server.ssl.enabled |
Boolean | true (when keystore set) |
Enable SSL |
server.ssl.key-store |
String | — | Path to keystore |
server.ssl.key-store-password |
String | — | Keystore password |
server.ssl.key-store-type |
String | PKCS12 |
Keystore type |
server.ssl.key-alias |
String | — | Key alias in keystore |
server.ssl.protocol |
String | TLS |
SSL protocol |
Tomcat-Specific Properties
| Property | Type | Default | Description |
|---|---|---|---|
server.tomcat.max-threads |
Integer | 200 |
Max worker threads |
server.tomcat.min-spare-threads |
Integer | 10 |
Min spare threads |
server.tomcat.max-connections |
Integer | 8192 |
Max connections |
server.tomcat.accept-count |
Integer | 100 |
Queue size when all threads busy |
server.tomcat.max-http-form-post-size |
DataSize | 2MB |
Max form POST size |
server.tomcat.accesslog.enabled |
Boolean | false |
Enable access log |
server.tomcat.remoteip.remote-ip-header |
String | — | Header for real client IP |
server.tomcat.remoteip.protocol-header |
String | — | Header for forwarded protocol |
DataSource Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.datasource.url |
String | — | JDBC URL |
spring.datasource.username |
String | — | Database username |
spring.datasource.password |
String | — | Database password |
spring.datasource.driver-class-name |
String | (auto-detected) | JDBC driver class |
spring.datasource.hikari.maximum-pool-size |
Integer | 10 |
HikariCP max pool |
spring.datasource.hikari.minimum-idle |
Integer | 10 |
HikariCP min idle |
spring.datasource.hikari.connection-timeout |
Long | 30000 |
Connection timeout (ms) |
JPA/Hibernate Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.jpa.hibernate.ddl-auto |
String | (context-dependent) | Schema management: none, validate, update, create, create-drop |
spring.jpa.show-sql |
Boolean | false |
Log SQL statements |
spring.jpa.open-in-view |
Boolean | true |
Open EntityManager in view interceptor |
spring.jpa.database-platform |
String | (auto-detected) | Hibernate dialect |
spring.jpa.generate-ddl |
Boolean | false |
Initialize schema from entities |
spring.jpa.properties.* |
Map | — | Pass-through Hibernate properties |
Warning
spring.jpa.open-in-view=true(the default) keeps the database session open during the entire HTTP request, which can mask lazy loading issues and hold connections longer. Set tofalsein production for predictable connection management.
Logging Properties
| Property | Type | Default | Description |
|---|---|---|---|
logging.level.root |
String | INFO |
Root log level |
logging.level.<logger> |
String | — | Logger-specific level |
logging.file.name |
String | — | Log file path |
logging.file.path |
String | — | Log file directory |
logging.pattern.console |
String | (default pattern) | Console log pattern |
logging.pattern.file |
String | (default pattern) | File log pattern |
logging.structured.format.console |
String | — | Structured format (ecs, logstash) |
logging.structured.format.file |
String | — | Structured format for file output |
Actuator Properties
| Property | Type | Default | Description |
|---|---|---|---|
management.endpoints.web.exposure.include |
List | health |
Endpoints to expose via HTTP |
management.endpoints.web.exposure.exclude |
List | — | Endpoints to exclude |
management.endpoints.web.base-path |
String | /actuator |
Base path for actuator endpoints |
management.server.port |
Integer | (same as app) | Separate port for management |
management.endpoint.health.show-details |
String | never |
never, when-authorized, always |
management.endpoint.health.show-components |
String | never |
Show component details |
management.prometheus.metrics.export.enabled |
Boolean | true |
Enable Prometheus export |
management.tracing.sampling.probability |
Float | 0.1 |
Trace sampling rate (0.0-1.0) |
management.otlp.tracing.endpoint |
String | — | OTLP tracing endpoint |
management.otlp.metrics.export.url |
String | — | OTLP metrics endpoint |
Spring Security Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.security.user.name |
String | user |
Default username |
spring.security.user.password |
String | (generated) | Default password |
spring.security.user.roles |
List | — | Default user roles |
spring.security.oauth2.client.registration.* |
Map | — | OAuth2 client registrations |
spring.security.oauth2.resourceserver.jwt.issuer-uri |
String | — | JWT issuer URI |
Docker Compose Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.docker.compose.enabled |
Boolean | true |
Enable Docker Compose support |
spring.docker.compose.file |
String | compose.yaml |
Path to compose file |
spring.docker.compose.lifecycle-management |
String | start-and-stop |
none, start-only, start-and-stop |
spring.docker.compose.skip.in-tests |
Boolean | true |
Skip in test contexts |
DevTools Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.devtools.restart.enabled |
Boolean | true |
Enable auto-restart |
spring.devtools.restart.poll-interval |
Duration | 1s |
Classpath poll interval |
spring.devtools.restart.quiet-period |
Duration | 400ms |
Quiet period before restart |
spring.devtools.livereload.enabled |
Boolean | true |
Enable LiveReload server |
spring.devtools.remote.secret |
String | — | Remote DevTools shared secret |
Kafka Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.kafka.bootstrap-servers |
String | localhost:9092 |
Broker addresses |
spring.kafka.consumer.group-id |
String | — | Consumer group ID |
spring.kafka.consumer.auto-offset-reset |
String | latest |
Offset reset policy |
spring.kafka.producer.key-serializer |
Class | StringSerializer |
Key serializer |
spring.kafka.producer.value-serializer |
Class | StringSerializer |
Value serializer |
gRPC Properties
| Property | Type | Default | Description |
|---|---|---|---|
spring.grpc.server.port |
Integer | 9090 |
gRPC server port |
spring.grpc.client.<name>.address |
String | — | Target address (static://host:port) |
4. Deployment & Scaling
Executable JAR Deployment
The standard deployment model — a single JAR containing everything:
# Build
./mvnw clean package -DskipTests
# or
./gradlew bootJar
# Deploy
java -jar target/my-app.jar \
--spring.profiles.active=prod \
--server.port=8080 \
-Xms512m -Xmx1g
The executable JAR uses Spring Boot's custom JarLauncher classloader that supports nested JARs — dependencies are stored as-is inside BOOT-INF/lib/ rather than being unpacked and merged.
Container Image Deployment
Buildpacks (recommended — no Dockerfile needed):
./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=myregistry/myapp:1.0
Dockerfile (manual control):
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY target/my-app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Layered Dockerfile (optimized for Docker layer caching):
FROM eclipse-temurin:21-jre-alpine AS builder
WORKDIR /app
COPY target/my-app.jar app.jar
RUN java -Djarmode=tools -jar app.jar extract --layers --launcher
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/app/dependencies/ ./
COPY --from=builder /app/app/spring-boot-loader/ ./
COPY --from=builder /app/app/snapshot-dependencies/ ./
COPY --from=builder /app/app/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
Tip
The layered approach separates dependencies (which rarely change) from application code (which changes often). Docker caches unchanged layers, dramatically reducing build times for iterative deployments.
Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: myregistry/myapp:1.0
ports:
- containerPort: 8080
- containerPort: 8081 # management port
env:
- name: SPRING_PROFILES_ACTIVE
value: prod
- name: SPRING_DATASOURCE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8081
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8081
initialDelaySeconds: 30
periodSeconds: 10
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 1000m
Scaling Considerations
| Aspect | Recommendation |
|---|---|
| Horizontal scaling | Spring Boot apps are stateless by default; scale by adding replicas behind a load balancer |
| Connection pooling | HikariCP (default) — tune maximum-pool-size based on (core_count * 2) + disk_spindles |
| Session management | Use Spring Session with Redis for distributed sessions across replicas |
| Graceful shutdown | Set server.shutdown=graceful and spring.lifecycle.timeout-per-shutdown-phase=30s |
| Virtual threads | Java 21+ with spring.threads.virtual.enabled=true — dramatically increases throughput for I/O-bound workloads |
GraalVM Native Image
Spring Boot supports ahead-of-time compilation to GraalVM native images:
./mvnw -Pnative native:compile
# or
./gradlew nativeCompile
Native images start in milliseconds with minimal memory, suitable for serverless and short-lived workloads. Requires GraalVM JDK and the native-maven-plugin or native Gradle plugin.
Warning
Native images have limitations: no runtime reflection (unless explicitly configured), no dynamic class loading, and some Spring features may require AOT hints. Use
@ImportRuntimeHintsorRuntimeHintsRegistrarto register reflection, resources, and proxies needed at runtime.
5. Operations
Health Monitoring
Spring Boot Actuator provides health indicators that aggregate into a composite health status:
/actuator/health
├── db (DataSourceHealthIndicator)
├── diskSpace (DiskSpaceHealthIndicator)
├── redis (RedisHealthIndicator)
├── kafka (KafkaHealthIndicator)
├── mongo (MongoHealthIndicator)
└── custom (your HealthIndicator beans)
Custom health indicator:
@Component
public class PaymentGatewayHealthIndicator implements HealthIndicator {
@Override
public Health health() {
boolean reachable = checkPaymentGateway();
if (reachable) {
return Health.up()
.withDetail("gateway", "responsive")
.withDetail("latencyMs", 45)
.build();
}
return Health.down()
.withDetail("gateway", "unreachable")
.build();
}
}
The health system uses a contributor registry (DefaultHealthContributorRegistry) that supports runtime registration and unregistration of health indicators. The registry is thread-safe with copy-on-write semantics for concurrent access. A reactive variant (DefaultReactiveHealthContributorRegistry) supports non-blocking health checks.
Kubernetes Health Probes
Spring Boot auto-creates readiness and liveness groups for Kubernetes:
management.endpoint.health.probes.enabled=true
# Auto-enabled when running in Kubernetes
| Probe | Endpoint | Behavior |
|---|---|---|
| Liveness | /actuator/health/liveness |
Indicates if the app is alive (restart if DOWN) |
| Readiness | /actuator/health/readiness |
Indicates if the app can accept traffic |
Note
Health groups can be customized:
management.endpoint.health.group.readiness.include=db,redisensures the readiness probe reports DOWN only if database or Redis is unavailable, not for unrelated indicators.
Security Auditing
Spring Boot Actuator includes an audit subsystem that tracks security events:
Captured events:
AUTHENTICATION_SUCCESS— successful loginAUTHENTICATION_FAILURE— failed login attemptAUTHENTICATION_SWITCH— user impersonation/switchingLOGOUT_SUCCESS— user logout- Authorization decisions (granted/denied)
The AuthenticationAuditListener converts Spring Security events into AuditEvent objects, capturing the principal name, source IP, and event details. The AuthorizationAuditListener tracks access decisions for authorization monitoring.
Custom audit events are published through the AuditEventRepository:
@Component
public class CustomAuditor {
private final AuditEventRepository repository;
public CustomAuditor(AuditEventRepository repository) {
this.repository = repository;
}
public void recordAction(String principal, String action, Map<String, Object> data) {
repository.add(new AuditEvent(principal, action, data));
}
}
Metrics and Observability
Spring Boot auto-configures Micrometer meter registries for multiple monitoring systems:
| System | Property | Format |
|---|---|---|
| Prometheus | management.prometheus.metrics.export.enabled=true |
/actuator/prometheus endpoint |
| Datadog | management.datadog.metrics.export.* |
Push to Datadog API |
| New Relic | management.newrelic.metrics.export.* |
Push to New Relic API |
| Graphite | management.graphite.metrics.export.* |
Push to Graphite |
| InfluxDB | management.influx.metrics.export.* |
Push to InfluxDB |
| OTLP | management.otlp.metrics.export.url |
Push via OTLP protocol |
Built-in metrics include:
- JVM memory, GC, threads, classloader statistics
- HTTP request/response timing and counts
- DataSource connection pool statistics
- Cache hit/miss rates
- Spring Integration message channel throughput
- Kafka consumer lag and producer throughput
Tip
Use
management.metrics.tags.application=my-appto add a global tag to all metrics, making it easier to filter by application in multi-service dashboards.
Logging Operations
Change log levels at runtime via the /actuator/loggers endpoint:
# View current level
curl http://localhost:8080/actuator/loggers/com.example
# Change level
curl -X POST http://localhost:8080/actuator/loggers/com.example \
-H "Content-Type: application/json" \
-d '{"configuredLevel": "DEBUG"}'
Application Info
The /actuator/info endpoint aggregates information from:
info.app.name=My Application
info.app.version=1.0.0
info.app.description=A Spring Boot service
# Build info (auto-populated by build plugin)
management.info.build.enabled=true
# Git info (from git.properties)
management.info.git.enabled=true
management.info.git.mode=full
# Java runtime info
management.info.java.enabled=true
# OS info
management.info.os.enabled=true
6. Performance
JVM Tuning
| Setting | Recommendation |
|---|---|
| Heap | -Xms512m -Xmx1g (set min = max to avoid resizing) |
| GC | -XX:+UseZGC (Java 21+) or -XX:+UseG1GC for low-latency |
| Direct memory | -XX:MaxDirectMemorySize for Netty/NIO workloads |
| Metaspace | Usually auto-managed; cap with -XX:MaxMetaspaceSize if needed |
Virtual Threads (Java 21+)
Enable virtual threads for dramatically improved I/O-bound throughput:
spring.threads.virtual.enabled=true
This configures Tomcat/Jetty to use virtual threads for request handling, allowing thousands of concurrent connections without the thread pool being the bottleneck.
Connection Pool Tuning
HikariCP (default connection pool) — key settings:
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.leak-detection-threshold=60000
Note
The optimal pool size formula:
connections = (core_count * 2) + effective_spindle_count. For a 4-core server with SSD, start with 10 connections. Monitor thehikaricp.connections.activemetric to tune.
Startup Optimization
- Lazy initialization:
spring.main.lazy-initialization=true— defer bean creation until first use (faster startup, slower first request) - AOT processing: Use GraalVM native image or Spring AOT for ahead-of-time compilation
- Class Data Sharing:
-XX:SharedArchiveFilefor reduced class loading time - Slim dependencies: Exclude unused starters and transitive dependencies
7. Security
Auto-Configured Security
When spring-boot-starter-security is on the classpath, Spring Boot auto-configures:
- All HTTP endpoints require authentication
- A default user (
user) with a generated password (logged at startup) - Form-based login at
/login - HTTP Basic authentication
- CSRF protection (enabled for browser clients)
- Security headers (X-Frame-Options, X-Content-Type-Options, etc.)
- Session fixation protection
Production Security Checklist
- [ ] Configure a proper user store (JDBC, LDAP, OAuth2 provider)
- [ ] Enable HTTPS (
server.ssl.*properties) - [ ] Set
server.error.include-stacktrace=neverandserver.error.include-message=never - [ ] Restrict Actuator endpoints:
management.endpoints.web.exposure.include=health,info - [ ] Use a separate management port:
management.server.port=8081 - [ ] Disable DevTools in production (automatic when running as JAR)
- [ ] Set
spring.jpa.open-in-view=falseto prevent lazy-loading security risks - [ ] Configure CORS:
@CrossOriginorWebMvcConfigurer.addCorsMappings() - [ ] Enable rate limiting (via Spring Cloud Gateway or a reverse proxy)
- [ ] Rotate secrets using environment variables or vault, not properties files
Caution
Never commit
application.propertiesfiles containing passwords, API keys, or other secrets to version control. Use environment variables, Spring Cloud Vault, Kubernetes Secrets, or AWS Secrets Manager for production secret management.
OAuth2 and OIDC
Spring Boot auto-configures OAuth2 login and resource server:
# OAuth2 Client (login with Google)
spring.security.oauth2.client.registration.google.client-id=your-client-id
spring.security.oauth2.client.registration.google.client-secret=your-secret
# OAuth2 Resource Server (JWT validation)
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.example.com
SAML2 Service Provider
spring.security.saml2.relyingparty.registration.my-idp.assertingparty.metadata-uri=https://idp.example.com/metadata
8. Developer Internals
Repository Structure
spring-boot/
├── build-plugin/
│ ├── spring-boot-gradle-plugin/ Gradle build plugin
│ ├── spring-boot-maven-plugin/ Maven build plugin
│ └── spring-boot-antlib/ Ant build support
├── buildpack/
│ └── spring-boot-buildpack-platform/ CNB lifecycle, Docker API
├── buildSrc/ Custom Gradle conventions
├── cli/
│ └── spring-boot-cli/ Command-line interface
├── configuration-metadata/
│ └── ...-changelog-generator/ Config property changelog
├── core/
│ ├── spring-boot/ Core runtime (SpringApplication, config, loader)
│ ├── spring-boot-autoconfigure/ Auto-configuration engine
│ ├── spring-boot-autoconfigure-processor/ Compile-time annotation processor
│ ├── spring-boot-docker-compose/ Docker Compose integration
│ ├── spring-boot-properties-migrator/ Deprecated property detection
│ ├── spring-boot-test/ Testing support
│ └── spring-boot-test-autoconfigure/ Test slice annotations
├── documentation/
│ └── spring-boot-docs/ Antora-based documentation site
├── integration-test/ Cross-module integration tests
├── loader/
│ ├── spring-boot-loader/ Executable JAR classloader
│ ├── spring-boot-loader-tools/ JAR repackaging tools
│ └── spring-boot-jarmode-tools/ Layer extraction tools
├── module/
│ ├── spring-boot-actuator/ Actuator endpoints core
│ ├── spring-boot-actuator-autoconfigure/ Actuator auto-config
│ ├── spring-boot-devtools/ Developer tools
│ ├── spring-boot-health/ Health contributor registry
│ ├── spring-boot-jackson/ Jackson ObjectMapper config
│ ├── spring-boot-jpa/ JPA/Hibernate integration
│ ├── spring-boot-security/ Security auto-config
│ ├── spring-boot-webmvc/ Spring MVC integration
│ ├── spring-boot-webflux/ WebFlux integration
│ ├── spring-boot-web-server/ Embedded server factories
│ ├── spring-boot-grpc-server/ gRPC server support
│ ├── spring-boot-grpc-client/ gRPC client support
│ ├── spring-boot-micrometer-metrics/ Metrics integration
│ ├── spring-boot-micrometer-tracing/ Distributed tracing
│ ├── spring-boot-opentelemetry/ OpenTelemetry support
│ └── ... (60+ additional modules)
├── platform/
│ └── spring-boot-dependencies/ Dependency BOM
├── smoke-test/ End-to-end smoke tests
├── starter/ ~60 curated starter POMs
├── system-test/ System-level tests
└── test-support/ Shared test utilities
Architecture Deep Dive
Auto-Configuration Mechanism
Auto-configuration classes are registered in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. Each class uses conditional annotations:
| Annotation | Condition |
|---|---|
@ConditionalOnClass |
Class exists on classpath |
@ConditionalOnMissingBean |
No existing bean of this type |
@ConditionalOnProperty |
Property has specific value |
@ConditionalOnWebApplication |
Web application context |
@ConditionalOnResource |
Resource exists on classpath |
@ConditionalOnSingleCandidate |
Exactly one candidate bean |
@ConditionalOnCloudPlatform |
Running on specific cloud |
Evaluation order is controlled by @AutoConfigureOrder, @AutoConfigureBefore, and @AutoConfigureAfter. The spring-boot-autoconfigure-processor generates metadata at compile time to optimize condition evaluation without loading classes.
Configuration Loading System
The org.springframework.boot.context.config package implements a pluggable configuration loading system:
ConfigDataEnvironmentPostProcessor— bootstraps the config loading pipelineConfigDataLocationResolver— resolves location strings (e.g.,classpath:,file:,optional:) to actual resourcesConfigDataLoader— loads configuration from resolved resourcesConfigData— container for loaded property sources with options (IGNORE_IMPORTS, IGNORE_PROFILES, PROFILE_SPECIFIC)ConfigDataActivationContext— tracks active profiles during loadingConfigTreePropertySource— supports config tree format (Kubernetes ConfigMap volume mounts)
The system supports import statements (spring.config.import) for loading from additional sources, enabling integration with Vault, Consul, and custom configuration servers.
Executable JAR Loader
Spring Boot's custom classloader (JarLauncher, WarLauncher) handles nested JAR files:
my-app.jar
├── META-INF/MANIFEST.MF (Main-Class: JarLauncher, Start-Class: com.example.MyApp)
├── org/springframework/boot/loader/ (loader classes)
├── BOOT-INF/
│ ├── classes/ (application classes)
│ ├── lib/ (dependency JARs, stored as-is)
│ └── classpath.idx (classpath ordering)
└── BOOT-INF/layers.idx (layer ordering for Docker)
The loader registers custom URL protocol handlers (jar:nested:) for accessing classes inside nested JARs without extraction. The jarmode=tools entry point provides layer extraction for optimized Docker builds.
Error Handling Architecture
Both MVC and WebFlux share the ErrorAttributes contract:
DefaultErrorAttributescaptures: timestamp, status, error, exception, message, errors (validation), trace, pathErrorAttributeOptionscontrols which fields are included based onserver.error.include-*properties- The error handling implements
HandlerExceptionResolver(MVC) /WebExceptionHandler(WebFlux) and stores error details in request attributes
Error attributes include:
- Binding errors: extracted from
BindingResultfor form validation failures - Method validation errors: from
MethodValidationResultfor parameter validation - Stack traces are optionally captured and included based on configuration
Docker Compose Integration
The org.springframework.boot.docker.compose.core package provides:
DockerCli— executes Docker CLI commands, parses outputDefaultDockerCompose— manages lifecycle (up, down, start, stop)DefaultConnectionPorts— maps container ports to host ports, handles ephemeral port assignmentDockerHost— resolves Docker host address (supports host networking mode)DockerCliInspectResponse— models Docker inspect output with Config, HostConfig, and NetworkSettings
Port mapping supports both TCP and UDP protocols, and handles IPv4 address filtering for multi-homed containers.
Module Reference
Core Runtime (core/spring-boot)
Key classes:
SpringApplication— entry point, bootstraps the application contextSpringApplicationBuilder— fluent API for customizing SpringApplicationApplicationRunner/CommandLineRunner— post-startup callback interfacesExitCodeGenerator— allows beans to influence the exit codeApplicationPidFileWriter— writes PID file for process management
CLI (cli/spring-boot-cli)
Entry point: SpringCli.main() — creates a CommandRunner named "spring" and registers commands via ServiceLoader<CommandFactory>.
Default commands (from DefaultCommandFactory):
version(VersionCommand) — printsSpring CLI v{version}init(InitCommand) — scaffolds a new project from start.spring.ioencodepassword(EncodePasswordCommand) — BCrypt password encoding
Built-in commands (registered in main):
help(HelpCommand) — displays help for commandshint(HintCommand) — provides shell auto-completion hints (hidden)shell(ShellCommand) — interactive shell mode
Extension: drop JARs in ${spring.home}/lib/ext/ — they are added to the classloader.
Build Plugins
Gradle plugin (build-plugin/spring-boot-gradle-plugin):
JavaPluginAction— registersbootJar,bootWar,bootRun,bootBuildImagetasksApplicationPluginAction— configures distribution plugin integrationDependencyManagementPluginAction— importsspring-boot-dependenciesBOMKotlinPluginAction— aligns Kotlin dependency versionsCyclonedxPluginAction— integrates SBOM generationJarTypeFileSpec— filters outdependencies-starteranddevelopment-toolJARs
Maven plugin (build-plugin/spring-boot-maven-plugin):
spring-boot:run— runs the application with fork/no-fork optionsspring-boot:repackage— creates the executable JAR/WARspring-boot:build-image/build-image-no-fork— builds OCI images using Buildpacksspring-boot:build-info— generatesbuild-info.propertiesspring-boot:aot-generate/aot-test-generate— AOT compilation
DevTools (module/spring-boot-devtools)
DevToolsSettings loads from META-INF/spring-devtools.properties across all JARs on the classpath:
restart.include.*— regex patterns for JARs to monitor for changesrestart.exclude.*— regex patterns for JARs to ignoredefaults.*— property defaults for development
The restart mechanism uses two classloaders: a base classloader (for stable libraries) and a restart classloader (for application classes). Only the restart classloader is discarded and recreated on changes.
Code Patterns and Conventions
| Pattern | Usage |
|---|---|
@NullMarked (package-level) |
All packages use jspecify @NullMarked — nullability is the default contract |
| Constructor injection | Preferred over field injection throughout |
@Conditional* annotations |
Auto-configuration guard pattern |
| Package-private classes | Implementation classes are package-private, interfaces are public |
| License headers | Apache 2.0 header on every source file |
| Test naming | *Tests.java suffix, @TestTemplate for parameterized tests |
| Gradle conventions | Custom org.springframework.boot.conventions plugin applied to all subprojects |
| Repository layout | src/main/java, src/test/java, src/intTest/java, src/dockerTest/java |
Testing Strategy
| Test Type | Location | Scope |
|---|---|---|
| Unit tests | src/test/java |
Single class/method, mocked dependencies |
| Integration tests | src/intTest/java |
Multi-component, real context |
| Docker tests | src/dockerTest/java |
Requires Docker daemon (container images, Testcontainers) |
| Smoke tests | smoke-test/ |
End-to-end application boot and feature verification |
| System tests | system-test/ |
Deployment verification, image tests |
Test infrastructure:
@GradleCompatibility— parameterized testing across Gradle versions@DisabledIfDockerUnavailable— skip Docker-dependent testsGradleBuildtest kit — fluent API for Gradle integration testsApplicationContextRunner— lightweight context testing without starting a full server
Potential Improvements
Based on community feature requests:
- gRPC observability —
GrpcExchangessupport in Actuator similar toHttpExchanges(issue #49828) - gRPC baggage propagation — automatic baggage propagation from gRPC metadata (issue #49832)
- gRPC TLS rotation — support for server and client TLS certificate rotation (issues #49833, #49831)
- Virtual thread schedulers — Task Scheduler and Executor with virtual threads (issue #49949)
- Kafka health — tie
@KafkaListenerhealth into Actuator Health (issue #49899) - MongoDB observability — configure MongoDB
MicrometerObservabilitySettings(issue #49186) - Actuator endpoint caching — support caching for endpoint read operations with parameters (issue #30696)
- OAuth2 + interface clients — auto-configuration for OAuth2 with interface HTTP clients (issue #46956)
- DataSource wrapping — allow autoconfigured DataSource beans to be wrapped in
TransactionAwareDataSourceProxy(issue #50062) - Nested configuration metadata — improved metadata for non-static nested classes and records (issues #50133, #50096, #50121)
Contributing
The project uses:
- License: Apache License 2.0
- Build: Gradle with custom convention plugins in
buildSrc/ - Style: Checkstyle configuration in
config/checkstyle/ - Kotlin style: Detekt configuration in
config/detekt/ - HTTP validation: nohttp configuration in
config/nohttp/ - Documentation: Antora-based site with AsciiDoc source in
documentation/spring-boot-docs/
# Build the project
./gradlew build
# Run tests
./gradlew test
# Run integration tests
./gradlew intTest
# Run Docker tests (requires Docker)
./gradlew dockerTest
Note
The project uses
mavenCentral()and a Shibboleth releases repository (for OpenSAML/Shibboleth dependencies used by SAML2 support). All dependency versions are managed by thespring-boot-dependenciesBOM in theplatform/directory.
9. Integration Points
Spring Ecosystem Integration
| Project | Integration |
|---|---|
| Spring Framework | Core IoC, AOP, MVC, WebFlux, Data, Security |
| Spring Data | Auto-configured repositories for JPA, MongoDB, Redis, etc. |
| Spring Security | Auto-configured authentication, authorization, OAuth2/OIDC |
| Spring Batch | Auto-configured job repository and launcher |
| Spring Integration | Auto-configured messaging channels |
| Spring Session | Distributed session management (Redis, JDBC, Hazelcast) |
| Spring Cloud | Service discovery, config server, circuit breakers |
| Spring HATEOAS | Hypermedia-driven REST APIs |
| Spring GraphQL | GraphQL API auto-configuration |
Third-Party Integration
| Technology | Starter | Auto-Configuration |
|---|---|---|
| Apache Kafka | spring-boot-starter-kafka |
Consumer/producer factories, admin client |
| RabbitMQ | spring-boot-starter-amqp |
ConnectionFactory, RabbitTemplate |
| Apache Artemis | spring-boot-starter-artemis |
JMS ConnectionFactory |
| Apache Pulsar | spring-boot-starter-pulsar |
PulsarClient, PulsarTemplate |
| Flyway | spring-boot-starter-flyway |
Schema migration at startup |
| Liquibase | spring-boot-starter-liquibase |
Schema migration at startup |
| Quartz | spring-boot-starter-quartz |
Scheduler, job store |
| Hazelcast | spring-boot-starter-hazelcast |
HazelcastInstance |
| Micrometer | spring-boot-starter-actuator |
MeterRegistry, tracing |
| OpenTelemetry | spring-boot-starter-opentelemetry |
OTLP export |
| Testcontainers | spring-boot-testcontainers |
@ServiceConnection |
| Docker Compose | spring-boot-docker-compose |
Service connection auto-discovery |
Testcontainers Service Connections
Spring Boot provides @ServiceConnection support for:
| Service | Container Class | Auto-Configured |
|---|---|---|
| PostgreSQL | PostgreSQLContainer |
DataSource |
| MySQL | MySQLContainer |
DataSource |
| MongoDB | MongoDBContainer |
MongoClient |
| Redis | GenericContainer (Redis) |
RedisConnectionFactory |
| Kafka | KafkaContainer |
KafkaProperties |
| RabbitMQ | RabbitMQContainer |
ConnectionFactory |
| Elasticsearch | ElasticsearchContainer |
RestClient |
| Cassandra | CassandraContainer |
CqlSession |
| Neo4j | Neo4jContainer |
Driver |
| Couchbase | CouchbaseContainer |
Cluster |
| LDAP | GenericContainer (OpenLDAP) |
LdapContextSource |
| Pulsar | PulsarContainer |
PulsarClient |
| Hazelcast | GenericContainer (Hazelcast) |
HazelcastInstance |
10. Troubleshooting
Diagnostic Approach
Application issue?
├── Won't start
│ ├── Check error message and stack trace
│ ├── Run with --debug for auto-config report
│ ├── Check /actuator/conditions (if partially started)
│ └── Verify Java version, dependency versions
├── Unexpected behavior
│ ├── Check active profiles: /actuator/env
│ ├── Check applied auto-configs: /actuator/conditions
│ ├── Check bean definitions: /actuator/beans
│ └── Check property sources: /actuator/env
├── Performance issue
│ ├── Check /actuator/metrics for JVM stats
│ ├── Check connection pool: hikaricp.* metrics
│ ├── Check GC activity: jvm.gc.* metrics
│ └── Enable heap dump: -XX:+HeapDumpOnOutOfMemoryError
└── Security issue
├── Check security filter chain ordering
├── Enable debug logging: logging.level.org.springframework.security=DEBUG
└── Check /actuator/httptrace for request history
Error: No qualifying bean of type 'X' available
Cause: Spring cannot find a bean to inject. Common reasons: missing component scan, missing starter, or missing @Component/@Service annotation.
Solution:
- Ensure the class is annotated with a stereotype annotation
- Verify the class is in a package scanned by
@SpringBootApplication - Check if auto-configuration is disabled for the relevant feature
Prevention: Keep all application classes in subpackages of the main application class package.
Error: Default security is misconfigured when spring-boot-actuator-autoconfigure is present and spring-boot-health is not
Cause: Dependency mismatch where Actuator auto-configuration expects the health module but it is not on the classpath. (Community issue #50190)
Solution:
- Ensure
spring-boot-starter-actuator(which transitively includes health) is used instead of cherry-picking individual actuator modules - If using custom module selection, add
spring-boot-healthexplicitly
Prevention: Use the actuator starter rather than individual module dependencies.
Error: Elasticsearch Rest5Client auto-configuration misconfigures underlying HTTP client
Cause: The auto-configuration for Elasticsearch's Rest5Client may apply incorrect HTTP client settings in certain configurations. (Community issue #50189)
Solution:
- Define a custom
RestClientBuilderbean to override auto-configuration - Explicitly configure Elasticsearch connection properties
Prevention: Test Elasticsearch connectivity in integration tests before deploying.
Warning
When upgrading Spring Boot versions, run your application with
spring-boot-properties-migratoron the classpath. It detects deprecated properties in your configuration and logs replacement suggestions at startup. Remove it after migration is complete.
11. Quick Reference
Spring Boot CLI Commands
| Command | Description |
|---|---|
spring version |
Display CLI version |
spring init [options] |
Generate a new project from start.spring.io |
spring encodepassword <password> |
BCrypt-encode a password |
spring help [command] |
Display help for a command |
spring shell |
Start interactive shell |
Gradle Plugin Tasks
| Task | Description |
|---|---|
bootJar |
Build executable JAR |
bootWar |
Build executable WAR |
bootRun |
Run the application |
bootBuildImage |
Build OCI container image |
Maven Plugin Goals
| Goal | Description |
|---|---|
spring-boot:run |
Run the application |
spring-boot:repackage |
Create executable archive |
spring-boot:build-image |
Build OCI container image |
spring-boot:build-info |
Generate build-info.properties |
spring-boot:aot-generate |
Generate AOT sources |
spring-boot:start / stop |
Start/stop for integration tests |
Actuator Endpoints
| Endpoint | Method | Description |
|---|---|---|
/actuator |
GET | List available endpoints |
/actuator/health |
GET | Application health |
/actuator/health/{group} |
GET | Health group (liveness, readiness) |
/actuator/info |
GET | Application info |
/actuator/metrics |
GET | Metric names |
/actuator/metrics/{name} |
GET | Metric details |
/actuator/env |
GET | Environment properties |
/actuator/env/{name} |
GET | Specific property |
/actuator/loggers |
GET | Logger levels |
/actuator/loggers/{name} |
POST | Change logger level |
/actuator/beans |
GET | All bean definitions |
/actuator/conditions |
GET | Auto-configuration evaluation |
/actuator/configprops |
GET | Configuration properties |
/actuator/mappings |
GET | Request mappings |
/actuator/scheduledtasks |
GET | Scheduled tasks |
/actuator/threaddump |
GET | Thread dump |
/actuator/heapdump |
GET | Heap dump (binary) |
/actuator/prometheus |
GET | Prometheus metrics |
/actuator/shutdown |
POST | Graceful shutdown (disabled by default) |
Common Annotations
| Annotation | Purpose |
|---|---|
@SpringBootApplication |
Main class (combines @Configuration, @EnableAutoConfiguration, @ComponentScan) |
@ConfigurationProperties |
Bind properties to a class |
@ConditionalOnClass |
Conditional on class presence |
@ConditionalOnMissingBean |
Conditional on bean absence |
@ConditionalOnProperty |
Conditional on property value |
@AutoConfiguration |
Mark as auto-configuration class |
@SpringBootTest |
Full integration test |
@WebMvcTest |
MVC layer test |
@DataJpaTest |
JPA layer test |
@MockitoBean |
Create Mockito mock bean |
@ServiceConnection |
Auto-configure from Testcontainer |
@EnableConfigurationProperties |
Enable config property binding |
@GrpcService |
Register gRPC service |