Spring Boot는 편한데, 편한 만큼 내가 안 한 일을 누가 했는지가 잘 안 보일 때가 있어요.컨트롤러 하나 만들었을 뿐인데 서버가 뜨고, JSON이 나가고, 설정 파일이 읽히고, 데이터베이스 연결까지 준비되는 장면을 보면 이런 생각이 들죠.
“이거 편하긴 한데, 내부에서 뭐가 움직이는 거지?”이 Spring Boot 글들은 그 질문을 따라가려고 만든 길이에요. Annotation 이름을 먼저 외우기보다, 내가 작성한 코드와 Spring Boot가 대신 준비한 일을 나눠서 보는 데 집중할게요. 처음 읽는 분은 “아, 그래서 서버가 뜨는구나” 정도만 잡아도 충분해요. 하지만 이 카테고리는 거기서 멈추지 않을 거예요. 같은 장면을 한 번 더 내려가서 누가 결정했는지, 어느 시점에 객체가 만들어지는지, 어떤 경계에서 기대와 다르게 동작하는지, 실무에서는 무엇을 확인해야 하는지까지 같이 볼 거예요.
지금은 여기서 시작하면 돼요
글이 많아 보여도 앞에서 잡은 개념이 뒤 글의 기준점이 되도록 이어져 있어요. 처음이라면 아래 순서대로 읽는 흐름이 가장 자연스러워요.-
왜 Spring과 Spring Boot가 필요했을까요?
객체를 직접 만들고 연결하던 코드가 왜 Spring 컨테이너로 옮겨갔는지, 그리고 Spring Boot가 어떤 반복 설정을 덜어주는지 큰 그림부터 잡아요. -
Spring Boot 프로젝트는 처음에 무엇을 만들어줄까요?
Spring Initializr와
spring init으로 만든 첫 프로젝트의 선택지, 빌드 파일,main클래스, 패키지 구조, DevTools의 역할을 살펴봐요. - IoC, DI, AOP는 왜 Spring을 읽는 세 가지 기준점일까요? 제어의 역전, 의존성 주입, 관점 지향 프로그래밍을 어려운 정의보다 먼저 코드 책임의 이동으로 잡아봐요.
-
main 메서드 하나가 어떻게 실행 중인 앱이 될까요?
SpringApplication.run이 환경을 준비하고 컨테이너를 만들고 웹 서버를 띄우는 큰 흐름을 따라가요. - ApplicationContext와 Bean은 왜 Spring이 소유한 객체일까요? Spring 컨테이너가 빈 정의를 모으고 실제 객체를 만들고 연결하는 흐름을, 생명주기와 scope까지 이어서 살펴봐요.
-
컴포넌트 스캔과 Bean 등록은 왜 가끔 내 클래스를 못 찾을까요?
컴포넌트 스캔,
@Bean, 조건부 등록이 각각 어떤 방식으로 빈을 등록하는지 보고, Spring Boot가 클래스를 못 찾는 흔한 이유를 정리해요. - 의존성 주입은 실제 코드에서 어떻게 읽어야 할까요? 생성자 주입, 선택적 의존성, 여러 빈 후보, 순환 의존성을 실제 서비스 코드 흐름으로 읽고 field injection이 오래 갈수록 불리해지는 이유를 살펴봐요.
-
AOP 프록시와 Annotation은 왜 기대와 다르게 동작할까요?
@Transactional같은 Annotation이 단순한 표시가 아니라 프록시를 통과하는 호출에서 동작하는 이유와 self-invocation 함정을 살펴봐요. - 스타터와 자동 설정은 왜 버전과 설정을 대신 맞춰줄까요? starter, BOM, dependency management, auto-configuration, 조건 평가 리포트를 통해 의존성 하나가 어떻게 실행 설정으로 이어지는지 살펴봐요.
- application.yml과 profile은 설정을 어떻게 바꿔줄까요? 외부 설정, Config Data, profile, 환경 변수, Configuration Properties, 검증, secret 경계를 한 흐름으로 읽어봐요.
- Spring Boot 4와 3은 무엇이 달라졌을까요? Spring Boot 4.x와 3.5.x의 기준선을 Java, Spring Framework, Jakarta EE, Servlet 컨테이너, starter, 테스트 의존성 관점에서 비교해요.
- 웹 요청은 Spring MVC 안에서 어떤 순서로 지나갈까요? DispatcherServlet, HandlerMapping, argument resolution, validation, HttpMessageConverter, exception handling까지 Spring MVC 요청 흐름을 한 번에 따라가요.
- REST API 설계와 에러 계약은 왜 컨트롤러 코드보다 먼저일까요? DTO, request와 response 모양, Bean Validation, Problem Details, error code, API versioning을 클라이언트와 서버의 약속으로 읽어봐요.
- JSON과 Jackson 3는 왜 API 호환성의 핵심일까요? Spring Boot 4.x의 Jackson 3 기본 흐름, JsonMapper, Jackson 2 마이그레이션, 날짜와 enum과 unknown field가 API 계약에 주는 영향을 살펴봐요.
- Todo API 첫 커밋은 어떻게 차근차근 만들까요? Spring CLI로 Java 21, Gradle wrapper 기반 프로젝트를 만들고 생성된 파일 확인부터 controller, service, repository, validation, 테스트까지 첫 커밋 흐름으로 따라가요.
- Spring MVC와 WebFlux는 언제 다르게 선택해야 할까요? Spring MVC와 WebFlux를 구버전/신버전 관계가 아니라 blocking I/O, non-blocking I/O, thread model, 라이브러리 선택의 차이로 읽어봐요.
-
WebSocket과 STOMP는 언제 실시간 연결에 필요할까요?
HTTP 요청-응답과 오래 열린 WebSocket 연결의 차이, STOMP destination, message broker,
@MessageMapping, SockJS fallback을 Spring Boot 흐름으로 읽어봐요. -
RestClient, WebClient, HTTP Interface는 언제 다르게 써야 할까요?
서버가 다른 서버를 호출할 때
RestClient,WebClient, HTTP Interface를 어떻게 고르고, timeout과 retry를 어디에 두어야 하는지 outbound API 경계로 읽어봐요. -
데이터 접근은 JDBC, JPA, R2DBC 중 무엇을 골라야 할까요?
JDBC와
JdbcClient, Spring Data JDBC, JPA, Spring Data repository, R2DBC를 최신순이 아니라 문제 모양과 실행 모델로 고르는 법을 살펴봐요. - JPA Entity 상태와 영속성 컨텍스트는 왜 헷갈릴까요? Entity가 새 객체, 관리되는 객체, 분리된 객체, 삭제 예정 객체로 바뀌는 흐름을 영속성 컨텍스트, dirty checking, lazy loading, N+1, auditing과 함께 읽어봐요.
-
트랜잭션 경계와 롤백은 왜 Annotation 하나로 끝나지 않을까요?
@Transactional이 시작되는 위치, commit과 rollback이 결정되는 시점, propagation과 self-invocation이 기대를 흔드는 이유를 service 경계와 테스트까지 이어서 살펴봐요. - Schema migration은 왜 Flyway와 Liquibase로 관리할까요? 테이블과 컬럼 변경을 서버 코드처럼 버전으로 남겨야 하는 이유를 Flyway, Liquibase, migration history, 배포 순서, rollback 기대까지 이어서 살펴봐요.
-
복잡한 query는 Querydsl과 Specification 중 무엇으로 풀어야 할까요?
Spring Data JPA에서 derived query method,
@Query, Specification, Querydsl을 언제 나눠 쓰는지 검색 조건, join, pagination, sorting 경계로 살펴봐요. - Redis cache와 session은 왜 성능을 올리면서 버그도 만들까요? Spring Boot에서 Redis cache와 Spring Session Redis를 같은 저장소처럼 보되, TTL, invalidation, key prefix, 분산 session 경계로 나누어 읽어봐요.
- MongoDB와 Elasticsearch는 왜 JPA보다 빠른 DB가 아닐까요? MongoDB, Elasticsearch, document model, search index를 JPA 대체재가 아니라 서로 다른 데이터 문제를 푸는 도구로 나누어 읽어봐요.
- Spring Security는 왜 filter chain부터 봐야 할까요? Spring Boot에 Security starter를 넣었을 때 모든 요청이 왜 갑자기 잠기고, 인증과 인가와 CSRF와 CORS가 filter chain 안에서 어떻게 나뉘는지 살펴봐요.
- JWT와 OAuth2 Resource Server는 왜 로그인 구현과 다를까요? JWT access token, OAuth2 login, resource server, issuer, JWK Set, scope, refresh token 경계를 Spring Security 요청 흐름으로 나누어 읽어봐요.
-
Method Security와 도메인 권한은 어디에 둬야 할까요?
URL 규칙만으로 부족해지는 소유권 검사, method security,
@PreAuthorize,@PostAuthorize, 도메인 권한 판단을 service 경계에서 읽어봐요. - Auth API는 실무 프로젝트처럼 어떻게 설계할까요? Spring Boot 4와 Java 21로 회원가입, Basic 자격 증명 교환, JWT Bearer 보호 API, refresh token 회전, JDBC 저장소, ProblemDetail을 구현하고 공개 저장소의 실행 가능한 코드와 15개 테스트로 확인해요.
- 테스트는 unit, slice, integration을 어떻게 나눠야 할까요? Spring 없는 unit test, MVC와 JDBC slice, 전체 bean graph를 여는 integration test, 실제 port를 여는 server test가 각각 무엇을 증명하고 놓치는지 살펴봐요.
- Testcontainers와 WireMock은 무엇을 진짜로 바꿔줄까요? 실제 PostgreSQL을 띄우는 Testcontainers, 외부 HTTP를 재현하는 WireMock, 서비스 사이 약속을 검증하는 contract test를 서로 다른 test 경계로 나누어 읽어봐요.
- Actuator의 health와 metrics는 운영에서 무엇을 알려줄까요? Health, info, metrics, Prometheus endpoint를 서로 다른 운영 질문으로 나누고, liveness와 readiness와 안전한 공개 범위를 살펴봐요.
- Micrometer tracing과 correlation ID는 한 요청을 어떻게 찾을까요? Metric에서 발견한 이상 징후를 trace와 log로 좁히고, trace ID, span ID, MDC, context propagation, sampling으로 여러 service를 지난 요청 하나를 찾아가요.
- Auth API에 metrics와 tracing을 실제로 어떻게 붙일까요? 기존 Auth API에 Actuator, Prometheus Counter, OpenTelemetry tracing, Jaeger, 작은 downstream을 붙이고, async context 단절과 장애 추적을 실제 실행 결과로 확인해요.
-
Application Event는 같은 앱 안에서 무엇을 느슨하게 만들까요?
ApplicationEventPublisher,@EventListener,@TransactionalEventListener로 component를 분리하고, 동기 실행과 transaction phase와 전달 한계를 함께 살펴봐요. - Kafka와 RabbitMQ는 event를 어떻게 다르게 전달할까요? Spring Boot에서 process 밖으로 message를 보내고, Kafka의 partition과 RabbitMQ의 exchange·queue를 비교하면서 idempotency, retry, dead-letter, ordering을 함께 설계해요.
이 길에서 계속 붙잡을 질문
Spring Boot를 읽을 때는 기능 이름보다 질문을 먼저 잡는 편이 덜 헷갈려요.- 내가 만든 클래스는 누가 객체로 만들까요?
- 필요한 객체는 누가 생성자에 넣어줄까요?
main메서드 하나가 왜 웹 서버 시작으로 이어질까요?- 스타터(starter)를 넣으면 왜 여러 라이브러리가 같이 따라올까요?
- 자동 설정(auto-configuration)은 언제 적용되고, 언제 물러날까요?
- 테스트에서는 왜 실행할 때와 다른 컨텍스트가 뜰까요?
- Annotation 하나를 붙였는데 실제로는 프록시(proxy), 조건(condition), 컨텍스트(application context) 중 어디가 움직인 걸까요?
- 운영에서 문제가 났을 때 로그, 설정, 빈 목록, 조건 평가 리포트 중 무엇부터 봐야 할까요?
자, 정리해볼까요?
- 처음이라면 위 목록을 차례대로 읽는 게 가장 자연스러워요.
- 이 카테고리는 Annotation 암기보다 프레임워크가 대신 한 일을 보이게 만드는 데 집중해요.
- 각 글은 쉬운 장면에서 시작하되, 나중에 인용해도 버틸 수 있도록 메커니즘과 실패 경계까지 함께 남겨요.
- 실제 파일명은 번호 없는 안정적인 slug를 쓰고, 읽는 순서는
docs.json의 navigation에서 관리해요.