Spring Framework manages application objects and infrastructure; Spring Boot supplies conditional assembly and application startup around that framework.
Learning roadmap
Read the contract, run the source-kit checks, and inspect a rejected input before extending the application. This subject covers Spring and Spring Boot together; Java language lessons remain in their own subject.
Prerequisites
Use Java object ownership, interfaces, exceptions and Maven builds before the framework-specific lessons.
Section lessons
- Spring Boot application bootstrap: package boundaries and startup failures
- Spring Boot auto-configuration: conditions and user-defined beans
- Spring Boot configuration properties: bind values and reject bad startup input
- Spring Boot profiles and property precedence: test the selected environment
- Spring Boot auto-configuration: register imports and let a user bean win
- Spring Boot property override: fail startup on the effective value
- Spring Boot command-line properties: test the effective value at startup
- Spring Boot Duration binding: make timeout units explicit
- Spring Boot configuration validation: reject an unusable relay before work starts
- Spring Boot configuration sources: test each deployment path, not a guessed order
- Spring Boot external config file: bind the value the process actually loads
- Spring Boot file versus command line: assert the bound result
- Spring Boot config validation: separate valid syntax from a safe relay setting
- Spring Boot and Flyway: choose who runs migrations before traffic starts
- Spring Boot profile files: bind only the selected environment override
- Spring Boot config import: fail startup when a required file is missing
- Spring Boot optional config import: know which default survives
- Spring Boot config source priority: a builder default may lose to a packaged file
- Spring Boot environment variables: bind the intended key, not a lookalike
- Spring Boot relative config imports: resolve from the declaring file
- Spring Boot environment binding: prove the value in a child JVM
- Spring Boot config precedence: command line beats a process variable
- Spring Boot environment validation: fail before a worker starts
- Spring Boot relative config import: change the working directory and inspect the value
- Spring Boot required import: fail when a relative file is missing
- Spring Boot nested config imports: each file becomes the next base directory
- Spring Boot nested import failure: a missing second hop must stop startup
- Spring Boot configtree: bind one file per property in a child JVM
- Spring Boot configtree versus environment: assert the effective value
- Spring Boot required configtree: reject an absent directory
- Spring Boot configtree validation: reject a present but unsafe value
- Spring Boot extensionless config file: give the loader a properties hint
Continue learning
Spring Core, Web APIs, Data & Transactions, Security, Testing, Production, Exercises, Quizzes, Projects.
New checked lessons
- Spring Boot ApplicationRunner and CommandLineRunner: parse arguments at startup
- Spring Boot runner failure: reject startup instead of accepting unsafe settings
Spring Cloud boundary lessons
- Spring Cloud release trains: pin the framework set before adding a starter
- Spring Cloud Config import: decide whether missing remote settings stop startup
Spring Cloud and Spring AI paths
For distributed configuration and calls, start with the Cloud release boundary, configuration import and retry contracts. For model-backed work, read request budgets, tenant-scoped retrieval and tool authorization.
Batch and module architecture
Read job identity before running a restartable import, then inspect chunk commits and module APIs.
Batch faults and module events
Check the Batch skip budget and the running inventory module slice.
Production failure boundaries
- Spring Data JPA bulk update: the managed entity can still hold the old value
- Spring Data JPA derived delete versus bulk delete: callbacks and memory cost
- Spring Data JPA pessimistic lock: hold it only through the stock decision
- Spring REQUIRES_NEW: budget the second database connection
- Spring imperative transaction: a worker thread does not inherit it
- Spring reactive transaction: subscription owns the context, not a thread
- Spring resource server JWT: validate both issuer and intended audience
- Spring Security 401 versus 403: authentication and access are separate failures
- Spring Security login session: rotate the identifier at authentication
- Spring behind a proxy: trust forwarded headers only after the edge strips them
Config Server and native release boundaries
- Spring Cloud Config label: pin a release to the configuration it was tested with
- Spring Cloud Config Git cache: a healthy server can still return stale properties
- Spring Cloud refresh: changed properties do not rebuild every dependency
- Spring AOT: profile and conditional beans become build-time decisions
- Spring native RuntimeHints: register resources reached only by name
Distributed Spring systems
- Spring Integration DirectChannel versus ExecutorChannel: where the transaction stops
- Spring Integration queue: bound memory and choose a real message store
- Spring Integration idempotent receiver: the metadata key is not the business commit
- Spring Integration poller: include receive and handler in the failure boundary
- Spring Cloud Stream consumer group: scale one logical reader without copying every event
- Spring Cloud Stream Kafka DLQ: stop poison messages without losing the trail
- Spring Cloud Stream producer failure: a sent message is not an accepted business command
- Spring Cloud Config label: pin a release to the configuration it was tested with
- Spring Cloud Config Git cache: a healthy server can still return stale properties
- Spring Cloud refresh: changed properties do not rebuild every dependency
- Spring AOT: profile and conditional beans become build-time decisions
- Spring native RuntimeHints: register resources reached only by name
- Spring @Scheduled on three replicas: the callback runs three times
OAuth2 authorization server
- Spring Authorization Server, OAuth2 client and resource server: three trust roles
- Spring Authorization Server JDBC state: clients, grants and consent across restarts
- Spring Authorization Server grants: PKCE for public clients, credentials for services
Sessions, messages and query execution
- Spring Session Redis across replicas: shared login state has a Redis failure boundary
- Spring Session cookie policy: SameSite, Secure and the reverse proxy
- Spring Session principal index: invalidate one operator's sessions safely
- Spring AMQP prefetch: bound unacknowledged messages before raising concurrency
- Spring AMQP poison messages: reject, requeue and dead-letter are different decisions
- RabbitTemplate confirms and returns: broker acceptance is not consumer completion
- Spring GraphQL @BatchMapping: collapse N+1 lookups without changing field behavior
- Spring GraphQL batch loader tenant scope: never key a shared cache by row ID alone
- Spring Boot tracing across RestClient: construct the client from Boot's builder
- Spring Boot observation context across @Async and Reactor handoffs
Edge and cache operation contracts
- Spring Redis cache TTL versus idle expiry: GETEX changes the read contract
- Spring Redis cache key schema: tenant, prefix and rollout version
- Spring Redis cache writer: compound operations and replica stampedes
- Spring Cloud Gateway filter order: pre and post phases reverse
- Spring Cloud Gateway rate limits: derive the key from authenticated identity
- Spring Cloud Gateway retry: idempotency, buffered bodies and the byte budget
- Spring WebSocket STOMP identity: authenticate the handshake, authorize destinations
- Spring STOMP slow clients: send buffer and message-size limits
- Spring STOMP simple broker versus relay: the multi-instance boundary
- Spring HTTP service client: the interface is a contract, not a transport policy
- Spring HTTP service client retries: an interface cannot prove the server did not commit
- Spring Boot Testcontainers: service connections and cached-context lifecycle
Operations and recovery contracts
- Spring Cloud Gateway circuit breaker: a fallback is an API response contract
- Spring Cloud Gateway route refresh: guard the actuator write boundary
- Spring Data Redis Cluster: key slots change multi-key operations
- Spring Redis cache outage: choose failure behavior per operation
- Spring STOMP broker relay: credentials and broker availability are separate from user identity
- Spring WebSocket reconnect: recover state after an unobserved gap
- Spring HTTP service groups: configure one host policy for several interfaces
- Spring WebClient exchangeToMono: decode the response inside its callback
- Reactive HTTP service client: the proxy returns a publisher, not a completed call
- Spring Boot Testcontainers and Flyway: let one owner prepare the test schema
- Spring Testcontainers parallel tests: one database can leak another test's rows
- Spring OAuth2 client tokens: bind the authorized client to the intended caller and host
Document data, search and method security
- Spring Data MongoDB optimistic locking: save the version you read
- Spring Data MongoDB tenant uniqueness: enforce it in an index
- Spring Data MongoDB transaction: keep every write in one client session
- Spring Data MongoDB bulk writes: fewer round trips, different lifecycle behavior
- Spring Data MongoDB change stream: resume token and idempotent projection
- Spring Data Elasticsearch write versus search: refresh is the visibility boundary
- Spring Data Elasticsearch sequence conflict: do not overwrite a newer projection
- Spring Data Elasticsearch mapping rollout: build a new index, then move the read alias
- Spring method security: authorization advice runs through the bean proxy
- Spring @PostAuthorize: denial happens after the method has run
Cassandra, Neo4j, Kubernetes and SAML
- Spring Data Cassandra partition keys: model the read before the row
- Spring Data Cassandra TTL: expiry is a storage and query cost
- Spring Data Cassandra paging state: continue the same bounded query
- Spring Data Neo4j relationships: save only the graph you own
- Spring Data Neo4j transaction: keep the command inside one managed unit
- Spring Data Neo4j version conflicts: reject a stale graph update
- Spring Cloud Kubernetes config import: make source precedence explicit
- Spring Cloud Kubernetes reload: decide which changes need a restart
- Spring Cloud Kubernetes discovery: choose API lookup or Service DNS
- Spring Security SAML relying party: align registration, ACS and metadata
- Spring Security SAML validation: signatures, audience and clock window
- Spring Security SAML attributes: map identity to local authority
Conditional writes, graph queries, cluster access and SAML sessions
- Spring Data Cassandra conditional insert: reserve one key once
- Spring Data Cassandra consistency: budget availability and staleness per operation
- Spring Data Cassandra @Version: a conflict is not a merge
- Spring Data Neo4j custom query: return one coherent root record
- Spring Data Neo4j tenant lookup: constrain before traversing
- Spring Data Neo4j relationship properties: preserve edge identity
- Spring Cloud Kubernetes permissions: scope the service account to its reads
- Spring Boot Kubernetes probes: separate startup, readiness and liveness
- Spring Cloud Kubernetes watcher scope: filter before broadcasting refresh
- Spring Security SAML logout: local session versus single logout
- Spring SAML session revocation: closing the browser is not deprovisioning
- Spring SAML certificate rollover: overlap trust without accepting unknown keys
Store and platform practice
- Spring Cassandra write and query contracts quiz
- Spring Neo4j graph mapping and query contracts quiz
- Spring Kubernetes configuration and probe quiz
- Spring SAML trust and session quiz
Web Development connection
Spring Boot Web Service Boundaries; Project: Spring Boot Permit Service Boundaries; Web Development: Spring Boot service contracts.
JPA query and transaction contracts
- Spring Data JPA entity graph for a bounded to-one read
- Spring Data JPA Specifications with a mandatory tenant predicate
- Spring Data JPA Page versus Slice: pay for totals only when needed
- Spring Data JPA count query for a joined Page
- Spring Data JPA saveAndFlush is a SQL boundary, not a commit
- Spring read-only transaction: performance hint, not a write guard
- Spring Data JPA auditing: record the actor at the write boundary
- Spring Boot Open EntityManager in View: close the response-time query gap
Spring testing boundaries
- Spring Data JPA test: flush and clear before trusting a read
- Spring Data JPA test against the deployment database dialect
- Spring Boot HTTP test: client rollback does not own server writes
- Spring MockMvc security test: run the application filter chain
- Spring TestContext cache: keep equivalent tests on one context shape
- Spring @MockitoBean override: a mock can remove advice from the tested bean
- Spring transactional event test: cross an actual commit boundary
- Spring scheduled worker test: inject a clock and call the work once
Container and security contracts
- Spring BeanFactoryPostProcessor: inspect definitions before instances exist
- Spring BeanPostProcessor: instance callbacks and the early-bean trap
- Spring FactoryBean: expose the product type without constructing it
- Spring SmartLifecycle phases: drain work before destroying dependencies
- Spring Resource Server JWT key rotation: overlap keys across token lifetime
- Spring password hash upgrade after a verified login
- Spring SecurityContext handoff to a bounded async executor
- Spring Security CORS preflight: evaluate origin before authentication
Management and cache contracts
- Spring Actuator management port: separate listener, explicit access rule
- Spring Prometheus scrape endpoint: registry, exposure and label contract
- Spring health details: status for probes, diagnostics for operators
- Spring cache after commit: keep rolled-back writes out of readers
- Spring null-result caching: decide whether a miss should survive
- Spring Redis cache serialization: roll payload formats without mixed readers
- Spring tracing and logs: preserve request identity across outbound calls
- Spring Actuator loggers endpoint: temporary diagnosis with guarded write access
Web runtime contracts
- Spring MVC async executor: bound Callable work before requests pile up
- Spring MVC streaming response: stop work when the client disconnects
- Spring WebFlux codec memory budget: distinguish aggregation from streaming
- Spring WebClient status-specific decoding: consume one branch and close the rest
Conditional auto-configuration contracts
- Spring Boot ConditionalOnMissingBean: a default that yields to application code
- Spring Boot ConditionalOnProperty: make optional infrastructure opt in
Virtual-thread admission
JPA identity and batching
Data and transactions now includes assigned-ID state, insert batching and collection fetch paging.
Security chain and token boundaries
Spring Security now includes multiple filter chains, JWT authority mapping and SPA CSRF token refresh.
Spring test isolation
Testing now covers MVC slices, SQL fixture transaction modes and preemptive timeout rollback risk.
Batch execution boundaries
Production now includes step-scoped readers, partition ownership and flow restart status.
Startup diagnostics and packaging boundaries
- Spring Boot FailureAnalyzer: turn one startup exception into an actionable failure
- Spring Boot condition report: locate the missing auto-configuration decision
- Spring Boot configuration-property scanning: keep the package boundary explicit
- Spring Boot layered jar: keep dependency changes out of the application layer
- Spring Boot buildpack image: separate build settings from deployed secrets
- Spring Boot executable jar: load resources through the classpath, not a file path
- Spring Boot process exit codes: make job failure visible to the scheduler
- Spring Boot DevTools restart: reproduce classloader failures without it
- Spring Boot context initializer: make pre-refresh customization narrow
