Spring Boot Course
Learn Spring Boot step by step: Spring Core, Spring MVC, Spring Data JPA, microservices and advanced topics, with real code examples and quizzes.
39 lessons in 5 categories
Spring Core
Dependency Injection & IoC
Inversion of Control, Dependency Injection, and constructor/setter/field injection in plain Java -- no Spring required.
Spring IoC Container & Bean Lifecycle
BeanFactory/ApplicationContext, the bean lifecycle, @PostConstruct/@PreDestroy, bean scopes, @Lazy, and resolving circular dependencies.
Component Scanning & Configuration
@Component/@Service/@Repository/@Controller stereotypes, @ComponentScan, @Autowired (field/setter/constructor), @Qualifier, and @Primary.
Spring Boot Auto-Configuration & Properties
@SpringBootApplication, the @Conditional family (@ConditionalOnClass/@ConditionalOnMissingBean/@ConditionalOnProperty), @Value, @ConfigurationProperties, @Profile, and ApplicationEvent/@EventListener.
Transaction Management
The proxy-based mechanism behind @Transactional, rollback rules, propagation (REQUIRED/REQUIRES_NEW), the self-invocation pitfall, isolation levels, readOnly, TransactionTemplate, and @TransactionalEventListener.
Spring MVC
Spring MVC Fundamentals
DispatcherServlet, the MVC pattern (Model/View/Controller), and the difference between @Controller and @RestController.
Mapping Annotations & HTTP Methods
@RequestMapping and its five shortcuts (@GetMapping/@PostMapping/@PutMapping/@PatchMapping/@DeleteMapping), consumes/produces, and the safe/idempotent semantics of HTTP methods.
Path Variables & Request Parameters
Reading data from a request's URL and headers with @PathVariable, @RequestParam, and @RequestHeader; the difference between a path variable and a query parameter.
Request and Response Handling
Turning a request body into an object with @RequestBody, taking full control of a response with ResponseEntity, HTTP status codes, and content negotiation.
Validation & Exception Handling
Bean Validation (@NotBlank, @Size, @Email, @Pattern) with @Valid, cascading for nested objects, @ExceptionHandler, @RestControllerAdvice, and standardized error handling with RFC 7807 ProblemDetail.
Spring MVC Views and Thymeleaf
Three ways to carry data to the view with Model, ModelMap, and ModelAndView; Thymeleaf's "natural templating" philosophy; Thymeleaf variable/link/message expressions (@{...}, #{...}, and dollar-brace variable access); th:if, th:each, th:fragment; SpringEL selection expressions (.?[...] / #vars); and MVC vs. REST, with reference to this project's own layout.
Advanced Spring MVC
HandlerInterceptor (preHandle/postHandle/afterCompletion) and the Filter vs. Interceptor distinction; registering interceptors and configuring global CORS with WebMvcConfigurer; same-origin policy, the preflight request, and @CrossOrigin; file uploads with MultipartFile and size limits.
REST API Design
The risks of returning an entity directly and the DTO pattern; pagination, sorting, and filtering with Pageable/Page/Sort and query parameters; URI versioning vs. header versioning; idempotency and making POST idempotent with the Idempotency-Key header; HATEOAS (a quick look).
Testing in Spring MVC
Web layer tests with MockMvc and @WebMvcTest; faking dependencies with @MockitoBean; verifying with model(), view(), and jsonPath(); testing request bodies, path variables/query params, validation errors, and multipart uploads; real tests of this project's own HomeController and TopicController.
Microservices
Microservices Fundamentals
The limits of monolithic architecture, the core characteristics of microservice architecture, defining service boundaries (bounded context), database per service, and a quick look at the CAP theorem and Conway's Law -- a conceptual introduction with no code.
Microservice Configuration
Configuring a single Spring Boot microservice (order-service) from the ground up: its own entry point, its own application.yml (port, application name, database), a REST controller as the API contract, the service layer, the domain model, and a health check.
Inter-Service Communication
Adding a second microservice (inventory-service) next to order-service and connecting the two with a synchronous REST call via Spring's RestClient: stock checking, error handling (what happens when a service is down), and separating DTOs between services. Links to the category's real, runnable Practical Project.
Service Discovery & Eureka
order-service now finds inventory-service by NAME instead of a hardcoded URL: the Eureka Server (a central registry), the Eureka Client (spring.application.name becoming the discovery key), direct queries with DiscoveryClient, calling by name with a @LoadBalanced RestClient, heartbeats/eviction/self-preservation mode, and why Eureka picks the AP side of the CAP theorem.
API Gateway
order-service and inventory-service becoming reachable to external clients through a single entry point: setting up a separate api-gateway application with Spring Cloud Gateway, the route predicate/URI/filter trio, discovery-based routing through Eureka with lb://, writing a custom GlobalFilter (the course's first reactive code), and why system-wide concerns like correlation ids belong at the gateway while business logic stays in the service.
Resilience4j
Taking order-service's inventory-service calls beyond manual try/catch error handling: applying Resilience4j's @CircuitBreaker (a CLOSED/OPEN/HALF_OPEN state machine) and @Retry annotations to ResilientStockClient, what fallback methods do when the circuit opens, why Spring's proxy mechanism doesn't work through self-invocation, and how a rate limiter/bulkhead protects against a different risk than a circuit breaker.
Configuration Management
Centralizing configuration every service has kept in its own application.yml so far, using Spring Cloud Config: setting up a separate config-server application with @EnableConfigServer, a Config Repository deciding what's genuinely worth centralizing, becoming a Config Client with spring.config.import, environment-specific overrides through profiles, refreshing configuration without a restart via @RefreshScope, and why secrets should never be stored in plain text.
Event-Driven Architecture & Kafka
Removing the time-coupling and direct-knowledge-coupling created by every inter-service call in this category being synchronous so far, using Kafka: topic/partition concepts, order-service publishing OrderPlacedEvent with KafkaTemplate, inventory-service reacting with @KafkaListener, when to choose synchronous vs. asynchronous, why at-least-once delivery requires every consumer to be idempotent, and the JSON serialization choice.
Distributed Transactions
Closing the gap the Event-Driven Architecture & Kafka lesson deliberately left open -- what happens to an order order-service already committed if inventory-service can't reserve stock: why Two-Phase Commit is rare in microservices, the Saga pattern (local transactions plus compensating actions), building a two-way saga flow with choreography and StockReservationFailedEvent, why compensation isn't a rollback, and how the Outbox pattern closes the risk of an event never being published.
Observability
Closing two threads the API Gateway and Resilience4j lessons deliberately left open: actually propagating the correlation id into order-service's own logs (MDC) and its outgoing calls to inventory-service, structured (JSON) logging, metrics with Micrometer/Actuator, how distributed tracing builds on the same correlation id concept, and how Resilience4j already integrates with Micrometer automatically.
Security
Closing the unconditional trust every lesson in this category has assumed so far: introducing Spring Security into the course for the first time, the authentication vs. authorization distinction, JWT's self-contained nature, validating JWTs INDEPENDENTLY at both api-gateway and order-service (zero trust), role-based authorization, and propagating identity across services the same way the correlation id already is.
Deployment
How this category's localhost assumption, present in every lesson so far, actually gets deployed in the real world: small images with multi-stage Dockerfiles, orchestrating the whole system (eureka-server, config-server, api-gateway, order-service, inventory-service, Kafka) in one docker-compose file, environment-variable configuration in containers, why depends_on isn't enough without a health check, and a brief, honest look at Kubernetes.
Advanced Spring
Java Bean Validation
Builds on Spring MVC's "Validation & Exception Handling" lesson -- sign constraints (@Positive/@PositiveOrZero/@Negative/@NegativeOrZero), date/time constraints (@Past/@Future/@PastOrPresent/@FutureOrPresent), precise decimal bounds (@DecimalMin/@DecimalMax/@Digits), customizing validation messages, custom constraint annotations with ConstraintValidator for cross-field validation, and validation groups. The 1st lesson in the Advanced Spring series.
Exception Handling
Builds on Spring MVC's "Validation & Exception Handling" and this category's "Java Bean Validation" -- what MethodArgumentNotValidException actually carries, turning validation failures into a ProblemDetail (including cross-field failures), custom ProblemDetail properties, mapping domain exceptions to the right HTTP status code (400/404/409/422/500), centralizing with ResponseEntityExceptionHandler, and safe error responses that don't leak internal details. The 2nd and final lesson in the Advanced Spring series.
Task Execution & Scheduling
Builds on the thread-pool foundation "Threads" covers at the language level -- Spring's TaskExecutor abstraction, background work with @Async and @EnableAsync, why self-invocation breaks @Async (the SAME proxy pitfall as "Transaction Management"), scheduling with @Scheduled's fixed rate/fixed delay/initial delay/cron expressions, and configuring scheduling's own separate thread pool (TaskScheduler). The 3rd lesson in the Advanced Spring series.
Spring Batch
Why large-scale batch processing needs a structure `@Scheduled` alone can't provide -- the Job/Step/chunk-oriented processing mental model, ItemReader/ItemProcessor/ItemWriter through a single CSV-to-database order import example, the JobParameters/JobInstance/JobExecution distinction, restartability via the JobRepository, skip/retry fault tolerance, and practical integration with `@Scheduled`. The 4th lesson in the Advanced Spring series.
Spring Data JPA
JPA, Hibernate, and Spring Data JPA
Starting from the problem of persisting a Java object into a database, this lesson builds the ORM → JPA (specification) → Hibernate (implementation) → Spring Data JPA (repository abstraction) → Spring Boot (auto-configuration) mental model using this project's own Topic/TopicRepository classes. The 1st lesson in the Spring Data JPA category.
Entities and the Repository Abstraction
@Entity/@Id/@GeneratedValue/@Column mapping, plus @Table/@Enumerated/nullable-unique constraints/the no-args-constructor requirement/entity vs. DTO/equals()-hashCode() (concisely), and what each tier of the Repository → CrudRepository → PagingAndSortingRepository → JpaRepository hierarchy actually contributes -- using this project's own Topic/Category/TopicRepository classes. The 2nd lesson in the Spring Data JPA category.
Query Methods and JPQL with @Query
How Spring Data JPA derives a query from a repository method's name (findBy/existsBy/countBy, And/Or/OrderBy), writing JPQL with @Query and named parameters, @Modifying for bulk updates/deletes, join fetch, and when to reach for a native query -- using this project's own real repositories. The 3rd lesson in the Spring Data JPA category.
Pagination, Sorting, and Projections
How the Pageable/Sort "REST API Design" resolves at the controller level actually becomes a real LIMIT/OFFSET plus count query at the repository level, sorting with findAll(Sort)/derived methods, and interface-based and record/constructor-expression projections that return only the fields a query needs instead of a whole entity -- using this project's own Topic/TopicTranslation classes. The 4th lesson in the Spring Data JPA category.
Dynamic Queries with Specifications
Delivers on the optional filtering "REST API Design" left in memory, pushing it into the database -- the Specification interface as a thin wrapper around JPA's own Criteria API (Root/CriteriaQuery/CriteriaBuilder/Predicate), JpaSpecificationExecutor, combining conditions with Specification.where/and/or, and combining with real pagination via findAll(Specification, Pageable) -- using this project's own Topic entity. The 5th lesson in the Spring Data JPA category.
Relationships, Fetching, and the N+1 Problem
@OneToMany/@ManyToMany mapping (beyond the @ManyToOne already covered in full in "Transaction Management"), cascade types (PERSIST/MERGE/REMOVE/ALL) and orphanRemoval, a concrete demonstration of the N+1 problem, and three different fixes with @EntityGraph/batch fetching/projections -- using this project's own Topic/Category/QuizQuestion classes. The 6th lesson in the Spring Data JPA category.
The Persistence Context and Locking
Why dirty checking, already covered in full in "Transaction Management," actually works -- the persistence context itself, entity lifecycle states (transient/managed/detached/removed), the first-level cache, persist/merge/detach, flush timing -- and what happens when two transactions touch the same row: optimistic locking with @Version, pessimistic locking with @Lock. The 7th lesson in the Spring Data JPA category.
Auditing in Spring Data JPA
Starting from this project's own real QuestionIngestService's hand-written LocalDateTime.now() pattern, this lesson covers @CreatedDate/@LastModifiedDate, wiring @EntityListeners(AuditingEntityListener.class) + @EnableJpaAuditing together, @CreatedBy/@LastModifiedBy, AuditorAware<T>, and sharing audit fields with @MappedSuperclass. The 8th lesson in the Spring Data JPA category.
Testing Spring Data JPA Repositories
@DataJpaTest and TestEntityManager, only named in "Testing in Spring MVC" -- closing the gap this project's own Mockito-mocked service tests leave open (nothing verifies a query actually works); testing a derived query method and a custom @Query, and embedded test database vs. real PostgreSQL vs. Testcontainers, grounded in this project's own application-test.yml comment. The 9th and final lesson in the Spring Data JPA category.