1. 학습 주제
- Spring Boot에서 HTTP 요청이 Controller 메서드로 어떻게 연결되는가
- AOP가 공통 코드를 어떻게 중간에 끼워 넣는가
이번 범위는 스프링이 왜 편한지 체감하기 시작하는 구간이다.
이전에는 직접 서블릿을 만들고, URL을 보고, if로 분기하고, request에서 값을 꺼냈다면
Spring Boot에서는 그 과정을 훨씬 자동화하고 선언적으로 바꿔준다.
또한 AOP는 처음 보면 추상적이지만,
결국 핵심은 **“중복되는 공통 코드를 핵심 로직 앞뒤에 자동으로 넣어주는 기술”**이다.
2. Spring Boot의 특징
필기에 적은 세 가지가 핵심이다.
1. 자동 설정
필요한 기본 설정을 Spring Boot가 알아서 구성해준다.
예를 들어 웹 프로젝트를 시작할 때:
- DispatcherServlet 등록
- JSON 변환 설정
- 기본 웹 환경 준비
같은 것들을 Spring Boot가 자동으로 세팅해준다.
즉 개발자가 처음부터 다 설정하지 않아도
“웹 프로젝트라면 보통 필요한 것들”을 기본값으로 맞춰주는 것이다.
2. Starter 의존성
웹 개발에 필요한 라이브러리 묶음을 한 번에 가져온다.
예를 들어 spring-boot-starter-web 같은 의존성을 추가하면:
- Spring MVC
- 내장 Tomcat
- JSON 처리 라이브러리
- 웹 관련 기본 기능
이 묶음으로 들어온다.
즉 필요한 라이브러리를 하나하나 다 찾지 않아도 된다.
3. 내장 서버
Tomcat을 따로 설치하지 않아도, main 메서드 실행만으로 웹 서버를 띄울 수 있다.
이게 정말 편한 이유는:
- 프로젝트 실행이 단순해지고
- 배포 구조도 쉬워지고
- 테스트하기도 편해지기 때문이다
즉 Spring Boot는
**“스프링 웹 애플리케이션을 훨씬 빠르고 편하게 시작하게 해주는 도구”**라고 보면 된다.
3. HTTP 요청은 어떻게 Controller 메서드로 가는가
이번 학습의 가장 중요한 흐름 중 하나는 이것이다.
기본 규칙
HTTP Method + URL -> Controller 메서드
예를 들어:
- GET /api/v1/menus
- POST /api/v1/menus
- PUT /api/v1/menus/3
- DELETE /api/v1/menus/2
이렇게 같은 /menus라도
HTTP 메서드가 다르면 호출되는 컨트롤러 메서드도 달라질 수 있다.
예를 들어 네가 적어준:
GET /api/v1/menus/1
이 요청은 보통
- GET
- /api/v1/menus/{menuCode}
형태의 매핑을 가진 메서드로 연결된다.
즉 Spring은 요청이 들어오면:
- URL을 보고
- HTTP 메서드를 보고
- 조건에 맞는 Controller 메서드를 찾아 실행한다
이게 Spring MVC 요청 처리의 핵심 감각이다.
4. @RestController의 역할
이번 예제는 대부분 JSON 응답을 반환하는 API 구조였다.
그래서 @RestController를 사용했다.
이건 쉽게 말하면:
- 이 클래스는 웹 요청을 처리하는 Controller이고
- 반환값은 주로 화면 이름이 아니라 JSON 응답 데이터다
라는 뜻이다.
즉 @RestController는
**“HTML 페이지 반환보다 API 응답에 더 적합한 컨트롤러”**라고 이해하면 된다.
5. 클래스 단위 요청 매핑
컨트롤러 클래스 위에 @RequestMapping을 붙이면
그 컨트롤러가 담당하는 공통 URL prefix를 줄 수 있다.
예를 들어:
- 메뉴 관련 기능은 /api/v1/menus
- 주문 관련 기능은 /api/v1/orders
이런 식으로 큰 주소 묶음을 만들 수 있다.
즉 클래스 단위 매핑은
**“이 컨트롤러는 이 큰 주소 그룹을 담당한다”**고 선언하는 것이다.
6. 메서드 단위 요청 매핑
그다음 각 메서드는 세부 요청을 처리한다.
예를 들어:
- @GetMapping : 조회
- @PostMapping : 등록
- @PutMapping : 수정
- @DeleteMapping : 삭제
이렇게 나누어진다.
즉 같은 /menus 아래에서도:
- GET -> 목록 조회
- POST -> 신규 등록
- PUT -> 수정
- DELETE -> 삭제
처럼 역할이 나뉜다.
이걸 REST 스타일 API의 기본 패턴이라고 보면 된다.
7. ResponseEntity는 왜 쓰는가
컨트롤러 메서드는 그냥 데이터만 반환할 수도 있지만,
ResponseEntity를 사용하면 더 명확하게 응답을 구성할 수 있다.
예를 들어:
- 상태 코드 200
- 상태 코드 201
- body 데이터
를 함께 다룰 수 있다.
즉 ResponseEntity는
“응답 본문 + 상태 코드”를 더 명확하게 표현하는 도구다.
예:
- 조회 성공 -> 200 OK
- 등록 성공 -> 201 Created
처럼 표현할 수 있다.
8. 핸들러 메서드란 무엇인가
핸들러 메서드는
실제로 요청을 받아 처리하는 Controller 안의 메서드다.
즉 Spring이 URL과 HTTP 메서드를 보고
최종적으로 “이 요청은 이 메서드가 처리해”라고 결정한 대상이 핸들러 메서드다.
예를 들어:
- 메뉴 목록 조회 메서드
- 메뉴 등록 메서드
- 메뉴 상세 조회 메서드
- 세션 저장 메서드
이런 것들이 다 핸들러 메서드다.
9. @RequestParam
@RequestParam은 쿼리스트링 값을 받을 때 사용한다.
예:
- /api/v1/menus?keyword=coffee&categoryCode=2&page=1
이 요청에서:
- keyword
- categoryCode
- page
값을 바로 메서드 파라미터로 받을 수 있다.
장점:
- 직접 request.getParameter()를 하지 않아도 된다
- 기본값 설정 가능
- 필수 여부 조정 가능
즉 @RequestParam은
**“URL 뒤에 붙는 ?key=value 값을 자바 변수로 받는 방식”**이다.
10. @PathVariable
@PathVariable은 URL 경로 일부를 변수처럼 받는 방식이다.
예:
- GET /api/v1/menus/1
여기서 1은 경로 일부다.
Spring은 이 값을 menuCode 같은 변수로 받을 수 있게 해준다.
즉 @PathVariable은
**“주소 자체에 포함된 값을 파라미터로 받는 방식”**이다.
이건 보통 특정 자원 하나를 식별할 때 많이 쓴다.
예:
- 특정 메뉴 조회
- 특정 주문 상세
- 특정 회원 정보
11. @RequestBody
@RequestBody는 요청 본문(body)에 들어 있는 JSON 데이터를 자바 객체로 바꿔준다.
예를 들어 클라이언트가 JSON을 보내면:
{
"name": "아이스 아메리카노",
"price": 5000,
"categoryCode": 2,
"orderableStatus": "Y"
}
Spring은 이걸 DTO 객체로 변환해서 컨트롤러 메서드에 넣어준다.
즉 @RequestBody는
“JSON 요청 -> 자바 객체” 변환의 핵심 어노테이션이다.
실무 API에서는 정말 자주 쓴다.
12. @RequestHeader, @CookieValue, HttpSession
이번 예제는 요청의 다양한 정보를 받는 방법도 함께 다뤘다.
@RequestHeader
- 요청 헤더 값 받기
- 예: User-Agent, Content-Type
@CookieValue
- 요청에 포함된 쿠키 값 받기
- 예: JSESSIONID
HttpSession
- 세션 값 저장/조회/만료 처리
즉 Spring Boot에서는 단순히 body나 query string뿐 아니라
헤더, 쿠키, 세션도 컨트롤러 메서드에서 자연스럽게 다룰 수 있다.
13. 요청 흐름 전체 정리
이번 범위의 핵심 흐름을 한 줄씩 적어보면:
- 브라우저가 요청을 보낸다
- Spring Boot가 URL과 HTTP 메서드를 본다
- 매핑 규칙에 맞는 Controller 메서드를 찾는다
- 쿼리스트링, 경로 변수, JSON body, 헤더, 쿠키, 세션 값을 자동으로 파라미터에 넣어준다
- Controller 메서드가 처리 후 응답을 만든다
- ResponseEntity로 상태 코드와 body를 반환한다
- 클라이언트가 그 결과를 받는다
즉 예전보다 훨씬 더 “선언적”이고, “자동화된” 구조다.
14. AOP란 무엇인가
이제 AOP 쪽을 보자.
AOP
공통 관심사를 핵심 로직에서 분리하고, 필요한 실행 지점에 자동으로 끼워 넣는 방식
이 문장을 쉬운 말로 바꾸면:
- 서비스 메서드마다 똑같이 반복되는 코드가 있을 때
- 그걸 메서드 안에 직접 다 쓰지 않고
- 바깥에서 공통으로 처리하게 만드는 기술
이다.
예를 들어 공통 관심사에는 이런 것들이 있다.
- 로그 찍기
- 실행 시간 측정
- 트랜잭션 처리
- 보안 검사
핵심 관심사는 실제 업무 로직이다.
- 회원 조회
- 회원 한 명 조회
- 주문 생성
- 결제 처리
즉 AOP는
“반복되는 공통 코드”와 “진짜 업무 코드”를 분리하는 기술이다.
15. AOP가 왜 필요한가
예를 들어 모든 서비스 메서드 앞에 이런 코드가 필요하다고 해보자.
System.out.println("메서드 시작");
그리고 끝날 때마다 이런 코드도 필요하다고 하자.
System.out.println("메서드 종료");
이걸 모든 서비스 메서드 안에 직접 넣으면:
- 코드가 반복되고
- 핵심 로직이 지저분해지고
- 수정할 때 여러 군데를 건드려야 한다
그래서 AOP는 이런 공통 기능을 따로 빼서
대상 메서드 앞뒤에 자동으로 적용한다.
16. 이번 예제의 AOP 흐름
네가 적은 흐름이 정확히 핵심이다.
흐름
memberService 호출
-> Spring Proxy 가 중간에서 가로챔
-> Pointcut 조건에 맞는지 확인
-> Advice 실행
-> 실제 MemberService 메서드 실행
-> Advice 후처리
-> 결과 반환 또는 예외 전달
이걸 하나씩 풀어보면 다음과 같다.
17. Spring Proxy란 무엇인가
AOP가 동작할 때 Spring은 실제 객체를 바로 주는 대신
그 앞에 Proxy(대리 객체) 를 둔다.
즉 사용자는 memberService를 호출한다고 생각하지만,
실제로는 먼저 Proxy가 요청을 받는다.
이 Proxy의 역할은:
- 지금 호출된 메서드가 AOP 적용 대상인지 확인
- 적용 대상이면 공통 기능 실행
- 그다음 실제 대상 객체(Target) 메서드 호출
즉 Proxy는 “중간 관리자” 같은 역할이다.
18. Target, Pointcut, Advice
Target
실제 핵심 로직이 들어 있는 객체
예: MemberService
Pointcut
어떤 메서드에 공통 기능을 적용할지 고르는 조건
예제에서는 서비스 클래스 메서드들을 대상으로 잡았다.
Advice
언제 어떤 공통 기능을 실행할지 정하는 것
예제에서는 @Before를 사용했으므로
실제 메서드 실행 전에 로그를 찍는다.
즉 구조를 다시 보면:
- Target: 실제 업무 메서드
- Pointcut: 적용 대상 조건
- Advice: 실행 시점과 공통 기능
이다.
19. @Aspect와 LoggingAspect
예제의 LoggingAspect는
AOP용 공통 기능 클래스였다.
- @Aspect : AOP 클래스라는 표시
- @Component : Spring Bean 등록
즉 이 클래스는 일반 서비스가 아니라
“공통 기능을 끼워 넣기 위한 Bean”이다.
그리고 Pointcut으로 서비스 메서드를 고르고,
@Before로 실행 전 로그를 찍는다.
즉 이번 예제의 핵심은
서비스 메서드 안에 직접 로그를 쓰지 않았는데도, 실행 전에 로그가 자동으로 출력된다는 점이다.
20. AOP를 가장 쉽게 이해하는 비유
AOP는 공연 비유로 많이 이해하면 쉽다.
- 핵심 관심사: 배우가 공연하는 것
- 공통 관심사: 조명, 방송, 입장 안내
배우는 공연만 하면 된다.
그런데 공연 시작 전에 항상 조명이 켜지고, 안내 방송이 나오고, 입장 확인이 된다.
이걸 배우가 직접 하지 않는다.
공통 시스템이 자동으로 처리한다.
AOP도 비슷하다.
즉 서비스는 회원 조회 같은 핵심 기능만 하고,
로그 출력 같은 공통 기능은 바깥에서 자동으로 붙는다.
21. “전이나 후 시점에 코드 삽입”의 의미
적어준 문장도 아주 중요하다.
AOP는
중복되는 공통 코드를 분리하고, 전이나 후 시점에 해당 코드를 삽입하는 방식
즉:
- 메서드 실행 전에 넣을 수도 있고
- 메서드 실행 후에 넣을 수도 있고
- 예외 발생 시 따로 처리할 수도 있고
- 전후를 감싸면서 실행할 수도 있다
이번 예제는 @Before라서 “실행 전”이다.
즉 AOP는 단순 로그 기능이 아니라
“실행 시점 제어” 관점으로 이해하는 게 좋다.
22. Spring Boot 요청 처리와 AOP를 연결해서 보기
이번 학습 내용을 연결해보면 이런 그림이 된다.
- 클라이언트가 GET /api/v1/menus/1 요청
- Spring Boot가 URL + HTTP Method 보고 적절한 Controller 메서드 선택
- Controller가 서비스 호출
- 서비스가 호출되기 직전에 Proxy가 가로챔
- Pointcut 조건 확인
- 조건에 맞으면 Advice 실행
- 실제 서비스 메서드 실행
- 결과 반환
- Controller가 응답 생성
- 클라이언트가 JSON 응답 받음
즉 Spring MVC는 “요청을 적절한 메서드로 연결”해주고,
AOP는 “그 메서드 실행 전후에 공통 기능을 자동 삽입”해준다고 보면 된다.
23. 이번 범위에서 핵심적으로 이해해야 할 것
1. Spring Boot는 요청 매핑을 자동화해준다
HTTP Method + URL을 기준으로 Controller 메서드가 정해진다.
2. 컨트롤러 메서드는 다양한 요청 데이터를 자연스럽게 받을 수 있다
- 쿼리스트링
- 경로 변수
- JSON 본문
- 헤더
- 쿠키
- 세션
3. AOP는 서비스 로직을 더 깔끔하게 만든다
로그 같은 반복 코드를 메서드 안에 직접 안 써도 된다.
4. Proxy가 핵심이다
AOP는 실제 객체를 바로 실행하는 게 아니라
Proxy가 중간에서 가로채기 때문에 가능하다.
24. 흐름 정리
Spring Boot
- 자동 설정
- Starter 의존성
- 내장 Tomcat
요청 매핑
- HTTP Method + URL -> Controller 메서드
- GET /api/v1/menus/1 -> 상세 조회용 메서드
핸들러 메서드
- @RequestParam
- @PathVariable
- @RequestBody
- @RequestHeader
- @CookieValue
- HttpSession
AOP
- 공통 관심사 분리
- Proxy가 서비스 호출을 가로챔
- Pointcut 확인
- Advice 실행
- 실제 메서드 실행
- 결과 반환
25. 핵심 정리
- Spring Boot는 자동 설정, Starter 의존성, 내장 서버를 통해 웹 개발을 훨씬 쉽게 시작하게 해준다.
- Spring MVC에서는 HTTP Method와 URL 조합으로 Controller 메서드가 결정된다.
- GET /api/v1/menus/1 같은 요청은 URL 패턴과 HTTP 메서드에 맞는 메서드로 연결된다.
- @RequestParam은 쿼리스트링, @PathVariable은 경로 변수, @RequestBody는 JSON 본문을 받을 때 사용한다.
- @RequestHeader, @CookieValue, HttpSession으로 요청의 부가 정보와 상태도 처리할 수 있다.
- AOP는 로그, 트랜잭션 같은 공통 관심사를 핵심 로직에서 분리하는 기술이다.
- AOP는 실제 대상 객체를 직접 실행하지 않고 Spring Proxy가 중간에서 가로채며 동작한다.
- Proxy는 Pointcut 조건을 확인하고, 맞으면 Advice를 실행한 뒤 실제 메서드를 호출한다.
- 이번 예제의 AOP는 서비스 메서드 실행 전 로그를 남기는 @Before 방식이었다.
- Spring Boot는 요청을 잘 연결해주고, AOP는 그 실행 전후에 공통 기능을 자동 삽입해준다고 이해하면 된다.
'TIL > [TIL]' 카테고리의 다른 글
| [TIL]Spring Boot 파일 업로드, 전역 예외 처리, 인터셉터 (0) | 2026.06.01 |
|---|---|
| [TIL]Spring Boot JSON 처리와 예외 흐름 기초 (0) | 2026.05.29 |
| [TIL]Spring Bean, DI, Life Cycle, Scope, 외부 설정값, AOP 정리 (0) | 2026.05.27 |
| [TIL]Spring Core: DI, Spring Container, Bean, 계층 구조, @Autowired와 컴포넌트 스캔 (0) | 2026.05.26 |
| [TIL]쿠키, 세션, 인증/인가, 그리고 Front Controller 흐름 (0) | 2026.05.22 |