Spring Boot & Spring MVC
Mid / SeniorAuto-configuration, externalized config, the DispatcherServlet request flow, filters vs interceptors, validation, the security filter chain, @Async, test slices, and Actuator.
Created 5 October 2026
10 concepts · detail hidden
01Spring vs Spring Boot
#c-spring-vs-spring-bootSpring Framework is the container, AOP, transactions, MVC, data access. Spring Boot is an opinionated layer on top that removes setup work:
- Auto-configuration — beans configured automatically based on the classpath and properties.
- Starters — curated dependency bundles (
spring-boot-starter-web,-data-jpa) with compatible versions managed by the Boot BOM. - Embedded server — Tomcat/Jetty/Undertow inside an executable jar (
java -jar app.jar) instead of deploying a WAR to a server. - Externalized configuration, Actuator (health, metrics, info endpoints), and production defaults.
Boot doesn’t add new runtime magic — it just registers ordinary Spring beans for you.
02@SpringBootApplication and how auto-configuration works
#c-springbootapplication-and-how-auto-configuration-works@SpringBootApplication=@SpringBootConfiguration(a@Configuration) +@ComponentScan(scan the main class’s package and sub-packages — classes outside it aren’t found) +@EnableAutoConfiguration.Auto-configuration classes are listed in
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsinside the Boot jars (Boot 2.7+; previouslyspring.factories). Each is a configuration class guarded by conditions:@AutoConfiguration @ConditionalOnClass(DataSource.class) @EnableConfigurationProperties(DataSourceProperties.class) public class DataSourceAutoConfiguration { @Bean @ConditionalOnMissingBean // back off if the user defined their own DataSource dataSource(DataSourceProperties props) { ... } }The key idea is
@ConditionalOnMissingBean— user configuration always wins: define your ownObjectMapperorDataSourcebean and Boot’s default backs off. To see what was applied and why, start with--debug(the conditions evaluation report) or use the Actuator/actuator/conditionsendpoint. Exclude one with@SpringBootApplication(exclude = DataSourceAutoConfiguration.class).03Externalized configuration and precedence
#c-externalized-configuration-and-precedenceProperty sources, from highest to lowest precedence (simplified):
- Command-line arguments (
--server.port=9090) SPRING_APPLICATION_JSON, JVM system properties (-D…)- OS environment variables (
SERVER_PORT=9090— relaxed binding) - Profile-specific files:
application-{profile}.yml(outside the jar beats inside) application.yml/application.properties(outside the jar beats inside)@PropertySourceand defaults
Profiles:
spring.profiles.active=prodactivatesapplication-prod.ymland@Profile("prod")beans. Secrets belong in environment variables or a secrets manager, not in committed YAML.- Command-line arguments (
04The DispatcherServlet request flow
#c-the-dispatcherservlet-request-flow- Request passes through the servlet filter chain (including Spring Security).
DispatcherServlet(the front controller) asks itsHandlerMappings which handler matches —RequestMappingHandlerMappingmaps URL + method to a@GetMappingmethod.HandlerInterceptor.preHandlefor each interceptor.HandlerAdapterinvokes the method: argument resolvers bind@PathVariable,@RequestParam,@RequestBody(via anHttpMessageConverter— Jackson for JSON) and run@Validvalidation.- Return value handled: for
@RestController/@ResponseBody, serialized by a message converter (content negotiation onAccept); otherwise resolved by aViewResolver. postHandle, thenafterCompletioninterceptors.- Exceptions anywhere in 3–5 go to
HandlerExceptionResolvers — including@ExceptionHandler/@ControllerAdvice. Global error handling — how a handler is chosen,ProblemDetailerror bodies, and what Boot does when nothing handles an exception — is covered in the Exception handling subtopic.
05Filters vs HandlerInterceptors vs AOP
#c-filters-vs-handlerinterceptors-vs-aopServlet FilterHandlerInterceptorAOP aspect Level Servlet container, before DispatcherServletSpring MVC, around the handler Any Spring bean method Sees Raw request/response; can wrap them Request + the resolved handler method Method arguments/return value Typical use Security, CORS, logging, compression, request ids Auth checks per handler, locale, timing Transactions, auditing, metrics on services Applies to Every request, including static resources and errors Only requests mapped to handlers Only proxied bean calls Rule of thumb: cross-cutting HTTP concerns → filter; concerns that need to know which controller method → interceptor; business-layer concerns → AOP.
06Validation — @Valid and @Validated
#c-validation-valid-and-validated@Valid @RequestBody CreateOrder bodytriggers Jakarta Bean Validation (@NotNull,@Size,@Emailon the DTO’s fields); failures →MethodArgumentNotValidException→ 400.@Validatedon a class enables method-level validation through a proxy (constraints on service method parameters,@ConfigurationPropertiesvalidation) and supports validation groups.@Validon a field cascades validation into nested objects.
07Spring Security's filter chain in one minute
#c-spring-securitys-filter-chain-in-one-minuteSpring Security is a chain of servlet filters:
DelegatingFilterProxy(registered with the servlet container) delegates toFilterChainProxy, which picks the first matchingSecurityFilterChainbean and runs its filters — CORS, CSRF, authentication (UsernamePasswordAuthenticationFilter,BearerTokenAuthenticationFilterfor JWT), thenExceptionTranslationFilterandAuthorizationFilter. A successful authentication is stored in theSecurityContextHolder(thread-local by default), which is what@PreAuthorize— another proxy-based feature, enabled with@EnableMethodSecurity— reads.Since Spring Security 6 you configure it by declaring a
SecurityFilterChain@Beanwith the lambda DSL;WebSecurityConfigurerAdapteris gone.08@Async and scheduling
#c-async-and-scheduling@EnableAsync+@Asyncruns a method on aTaskExecutorvia a proxy — so the same self-invocation and visibility rules apply. ReturnvoidorCompletableFuture<T>; exceptions fromvoidmethods go to anAsyncUncaughtExceptionHandler, otherwise they’re easy to lose. The async thread has no transaction, noSecurityContextand no request scope from the caller unless you propagate them (e.g. aTaskDecorator). Configure a bounded executor rather than relying on the default.@Scheduled(fixedRate = …)/cronwith@EnableSchedulingruns on a single scheduler thread by default — one slow job delays the others — and every instance of a horizontally scaled app runs it (use ShedLock or a distributed scheduler).09Testing — @SpringBootTest vs test slices
#c-testing-springboottest-vs-test-slices@SpringBootTest— full application context; most realistic, slowest. Combine withwebEnvironment = RANDOM_PORTfor real HTTP tests.@WebMvcTest(OrderController.class)— only the MVC layer (controllers, advice, filters, converters) withMockMvc; services are mocked.@DataJpaTest— only JPA: entities, repositories, an embedded or Testcontainers database; each test transactional and rolled back.@JsonTest,@RestClientTest— other slices.
Mock beans with
@MockitoBean(Spring Framework 6.2+; Boot’s@MockBeanis deprecated since Boot 3.4). Each distinct set of mocked beans/config creates a new cached context — mocks sprinkled differently across test classes slow suites down. Testcontainers with@ServiceConnectionruns a real PostgreSQL in Docker — preferred over H2, whose SQL dialect and locking behaviour differ from production.10Actuator essentials
#c-actuator-essentialsspring-boot-starter-actuatorexposes operational endpoints:/actuator/health(with liveness/readiness groups for Kubernetes probes, aggregating DB, disk, broker checks),/actuator/metricsand/actuator/prometheus(Micrometer),/actuator/info,/actuator/env,/actuator/loggers(change log levels at runtime),/actuator/threaddump. Onlyhealthis exposed over HTTP by default; expose others deliberately (management.endpoints.web.exposure.include) and secure them —envandheapdumpleak secrets.