본문 바로가기
Spring

TIL-10 빈 스코프와 Provider

by 다오__ 2023. 5. 23.

스코프의 특징

스코프는 환경에서만 동작한다.

스코프는 프로토타입과 다르게 스프링이 해당 스코프의 종료시점까지 관리한다. 따라서 종료 메서드가 호출된다.

 

스코프의 종류

request : HTTP 요청 하나가 들어오고 나갈 가지 유지되는 스코프, 각각의 HTTP 요청마다 별도의 인스턴스가 생성되고, 관리된다.

session : HTTP Session과 동일한 생명주기를 가지는 스코프

application : 서블릿 컨텍스트(ServletContext)와 동일한 생명주기를 갖는다.

websocket : 소켓과 동일한 생명주기를 갖는다.

 

 

 

스코프는 환경에서만 동작하므로 web 환경이 동작하도록 라이브러리를 추가하자.

 

build.gradle 추가하기

 

 

이제 hello.core.CoreApplication main 메서드를 실행하면 어플리케이션이 실행된다

 

 

[포트 바꾸는법]

main/resources/application.properties

```

server.port = 9090

```

 

그래서 request 스코프 언제쓰면 좋은가

 

동시에 여러 HTTP 요청이 오면 정확히 어떤 요청이 남긴 로그인지 구별하기 어렵다.

이럴때 사용하기 좋은것이 request스코프이다.

 

우리가 기대하는 공통의 포멧 : [UUID][requestURL]{message}

 

UUID 사용해서 HTTP 요청을 구분하자.

requestURL 정보도 추가로 넣어서 어떤 URL 요청해서 남은 로그인지 확인해보자

 

*UUID : Universally Unique Identifier 범용 고유 식별자

 

common 패키지에 MyLogger 클래스를 만들자

 

 

이제 MyLogger 달고 web 패키지안에 LogDemoService LogDemoController를 만들어보자

 

 

 

 

 

*인터셉터 : HTTPRequest controller 호출 직전에 공통화해서 처리를 있다

 

 

 

 

 

 

 

 

그런데 실행이 되지 않는다…

이유가 무엇일까?

 

 


런타임이 되면 스프링 컨테이너에서 LogDemoService MyLogger 주입받는다. 하지만

MyLogger Scope 확인해보자

 

 

 

MyLogger Scope request 클라이언트의 요청이 있을 ~ 요청이 빠져 나갈 까지의 생명주기를 가지므로 실행 시에는 MyLogger 스프링 컨테이너에 존재하지 않게된다. 따라서 주입을 받을 없고 실행 오류가 발생한다.

 

 

스프링 애플리케이션을 실행하는 시점에 싱글톤 빈은 생성해서 주입이 가능하지만, request 스코프 빈은 생성되지 않는다

즉 이 빈은 실제 클라이언트 요청이 와야 생성할 있다

 

 

 

이럴때 우리는 Provider 사용하면 해결할 있다.

간단히 ObjectProvider 사용해보자

 

스코프와 Provider

 

LogDemoController.class

 

 

 

LogDemoService.class

 

 

드디어 실행이 되었다.

 

Url 접속해보자

 

로그확인

 

클라이언트 요청 -> logDemo메서드 myLoggerProvider.getObejct() myLogger 생성  -> init 호출 -> UUID 생성 request 연결 -> myLogger.setRequestURL(URL) url 붙이고 -> log출력(컨트롤러 - 서비스) -> close 호출 -> 클라이언트 요청 종료

 

핵심은 요청이 들어오면 객체를 각각 요청별로 따로 관리해준다는 것이 핵심이다.

 

ObjectProvider 덕분에 ObjectProvider.getObject() 호출하는 시점까지 request.scope 빈의 생성을 지연시킬 있었다.

ObjectProvider.getObject() 호출하는 시점에는 HTTP요청이 진행중이므로 request.scope빈의 생성이 정상 처리된다.

ObjectProvider.getObject() LogDemoController, LogDemoService에서 각각 한번씩 따로 호출해도 같은 HTTP요청이면 같은 스프링 빈이 반환된다

 

 

 

 

 

'Spring' 카테고리의 다른 글

스프링 IoC 와 DI  (0) 2023.06.14
Gradle  (2) 2023.06.12
TIL-8 빈 스코프 프로토타입-2  (0) 2023.05.22
TIL-7 빈 스코프 프로토타입-1  (0) 2023.05.19
TIL-6 빈 생명주기 콜백  (1) 2023.05.18