TIL/[TIL]

[TIL]Spring Boot 요청 매핑, 핸들러 메서드, 세션 처리, 그리고 AOP

namerong 2026. 5. 28. 15:24

1. 학습 주제

  1. Spring Boot에서 HTTP 요청이 Controller 메서드로 어떻게 연결되는가
  2. 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은 요청이 들어오면:

  1. URL을 보고
  2. HTTP 메서드를 보고
  3. 조건에 맞는 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. 요청 흐름 전체 정리

이번 범위의 핵심 흐름을 한 줄씩 적어보면:

  1. 브라우저가 요청을 보낸다
  2. Spring Boot가 URL과 HTTP 메서드를 본다
  3. 매핑 규칙에 맞는 Controller 메서드를 찾는다
  4. 쿼리스트링, 경로 변수, JSON body, 헤더, 쿠키, 세션 값을 자동으로 파라미터에 넣어준다
  5. Controller 메서드가 처리 후 응답을 만든다
  6. ResponseEntity로 상태 코드와 body를 반환한다
  7. 클라이언트가 그 결과를 받는다

즉 예전보다 훨씬 더 “선언적”이고, “자동화된” 구조다.


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를 연결해서 보기

이번 학습 내용을 연결해보면 이런 그림이 된다.

  1. 클라이언트가 GET /api/v1/menus/1 요청
  2. Spring Boot가 URL + HTTP Method 보고 적절한 Controller 메서드 선택
  3. Controller가 서비스 호출
  4. 서비스가 호출되기 직전에 Proxy가 가로챔
  5. Pointcut 조건 확인
  6. 조건에 맞으면 Advice 실행
  7. 실제 서비스 메서드 실행
  8. 결과 반환
  9. Controller가 응답 생성
  10. 클라이언트가 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. 핵심 정리

  1. Spring Boot는 자동 설정, Starter 의존성, 내장 서버를 통해 웹 개발을 훨씬 쉽게 시작하게 해준다.
  2. Spring MVC에서는 HTTP Method와 URL 조합으로 Controller 메서드가 결정된다.
  3. GET /api/v1/menus/1 같은 요청은 URL 패턴과 HTTP 메서드에 맞는 메서드로 연결된다.
  4. @RequestParam은 쿼리스트링, @PathVariable은 경로 변수, @RequestBody는 JSON 본문을 받을 때 사용한다.
  5. @RequestHeader, @CookieValue, HttpSession으로 요청의 부가 정보와 상태도 처리할 수 있다.
  6. AOP는 로그, 트랜잭션 같은 공통 관심사를 핵심 로직에서 분리하는 기술이다.
  7. AOP는 실제 대상 객체를 직접 실행하지 않고 Spring Proxy가 중간에서 가로채며 동작한다.
  8. Proxy는 Pointcut 조건을 확인하고, 맞으면 Advice를 실행한 뒤 실제 메서드를 호출한다.
  9. 이번 예제의 AOP는 서비스 메서드 실행 전 로그를 남기는 @Before 방식이었다.
  10. Spring Boot는 요청을 잘 연결해주고, AOP는 그 실행 전후에 공통 기능을 자동 삽입해준다고 이해하면 된다.