이번 강의에서는
대부분의 컨트롤러에서 반복되던 공통 기능(특히 인증 관련 로직)을 모으기 위해
Rq라는 클래스를 만들고, 이를 @RequestScope 빈으로 등록했다.
이번 강의의 핵심은 단 하나다.
👉 “요청 하나당 하나의 Rq 객체”를 만들어서
👉 현재 요청에 대한 공통 정보(예: 로그인한 사용자)를 관리하자
이전 코드들을 보면 컨트롤러마다 계속 이런 코드가 반복되었다.
Bearer 제거예를 들면 이런 코드다.
String apiKey = authorization.replace("Bearer ", "");
Member actor = memberService.findByApiKey(apiKey)
.orElseThrow(() -> new ServiceException("401-1", "존재하지 않는 apiKey 입니다."));
👉 이 코드는
모든 컨트롤러에 거의 똑같이 등장했다.
그래서 강의에서는 이렇게 생각한 것이다.
“이걸 컨트롤러마다 쓰지 말고
요청 단위로 공통 관리하는 객체로 빼자”
그 결과가 바로 Rq 클래스다.
@Component
@RequestScope
public class Rq {
public Member getActor() {
return null;
}
}
아직 메서드 내용은 비어 있지만,
이 클래스의 역할과 스코프 자체가 핵심이다.
Rq는 앞으로 다음 역할을 맡게 된다.
@Component
👉 “이 클래스는 스프링 빈이다”라고 알려주는 어노테이션이다.
new Rq()를 직접 호출하지 않아도 됨📌 쉽게 말하면:
“스프링 컨테이너가 관리하는 객체”
@RequestScope
👉 HTTP 요청 하나당 새로운 객체를 만든다는 의미다.
동작 흐름은 이렇다.
📌 즉,
👉 완전히 다른 객체이며 절대 공유되지 않는다.
이 부분이 가장 헷갈리기 쉬운 포인트다.
| 어노테이션 | 역할 |
|---|---|
| @Component | 스프링 빈으로 등록 |
| @RequestScope | 생성 시점을 요청 단위로 제한 |
즉,
“스프링이 관리하되, 요청마다 새로 만든다”
이 조합 덕분에
Rq는 전역처럼 쓰이지만, 실제로는 요청마다 분리된 객체가 된다.
처음에는 이런 생각이 든다.
“중복 코드면 그냥 함수로 빼면 되지 않나?”
이 생각은 아주 정상적인 초보자 관점이다.
하지만 함수에는 한계가 있다.
즉, 같은 요청인데도
getActor()를 여러 번 호출하면
매번 apiKey 파싱 + DB 조회가 반복된다.
👉 함수는 상태를 저장할 공간이 없다.
다음으로 자연스럽게 드는 생각은 이거다.
“그럼 함수 말고 클래스로 만들면 되는 거 아닌가?”
이 질문도 정확하다.
실제로 방법은 있다.
Rq rq = new Rq(...);
Member actor = rq.getActor();
이 방식은 동작은 한다.
하지만:
new Rq() 필요👉 자바 코드로는 맞지만, 스프링스러운 구조는 아니다.
이 방식은 절대 하면 안 된다.
웹 서버는 여러 요청을 동시에 처리한다.
👉 이는 치명적인 보안 사고다.
@Component
@RequestScope
public class Rq {
private Member actor;
}
이 구조의 핵심은:
여기서 말하는 “기억”이란:
요청 하나가 처리되는 동안만 값을 필드에 저장해두고 재사용한다는 뜻이다.
👉 다음 요청으로 넘어가지 않는다.
👉 서버에 남아 있지 않는다.
| 구분 | Singleton (기본) | RequestScope |
|---|---|---|
| 생성 시점 | 애플리케이션 시작 시 1번 | HTTP 요청마다 |
| 인스턴스 수 | 딱 1개 | 요청 수만큼 |
| 상태 공유 | 모든 요청이 공유 | 요청별 독립 |
| 스레드 안전 | 직접 관리 필요 | 기본적으로 안전 |
| 사용 예 | 설정, 서비스 | 로그인 사용자, 요청 컨텍스트 |
📌 Rq는 무조건 RequestScope여야 한다.
컨트롤러에서는 더 이상 이런 걸 직접 하지 않는다.
String apiKey = ...
Member actor = ...
대신 이렇게 된다.
Member actor = rq.getActor();
👉 인증 로직이 한 곳으로 모인다
👉 컨트롤러는 “요청 처리”에만 집중
👉 코드 중복 제거 + 가독성 상승
@Component
→ 스프링이 관리하는 빈
@RequestScope
→ HTTP 요청마다 새 객체 생성
Rq 클래스의 목적
→ 요청 단위 공통 정보 저장소
왜 필요한가?
→ 인증/인가 로직 중복 제거 + 요청별 안전한 상태 관리
이번 글에서는
👉 “왜 Rq가 필요하고, 왜 RequestScope인지”
이 부분만 이해하면 충분하다.