웹스코프
➡️ 웹 스코프
🔸웹 환경에서만 동작
🔸스프링이 해당 스코프의 종료 시점까지 관리 >> 종료 메서드 호출
🔸request : HTTP 요청 하나가 들어오고 나갈 때까지 유지. 각각의 요청마다 별도의 인스턴스 생성, 관리
🔸session : HTTP Session과 동일한 생명주기
🔸application : 서블릿 컨텍스트(ServletContext)와 동일한 생명주기
🔸websocket : 웹 소켓과 동일한 생명주기
request 스코프 예제 만들기
➡️ 웹 라이브러리 gradle에 추가
implementation 'org.springframework.boot:spring-boot-starter-web'
🔸request scope 빈 생성 전에 (웹 리퀘스트가 들어오기 전에) 요청하기 때문에 예외 발생 >> Provider로 해결 가능
package hello.core.common;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
@Scope("request")
public class MyLogger {
private String uuid;
private String requestURL;
public void setRequestURL(String requestURL) {
this.requestURL = requestURL;
}
public void log(String message){
System.out.println("[" + uuid + "]" + "[" + requestURL + "]" + message);
}
@PostConstruct
public void init(){
uuid = UUID.randomUUID().toString(); // UUID 만들어주는 메서드
System.out.println("[" + uuid + "] request scope bean create:" + this );
}
@PreDestroy
public void close(){
System.out.println("[" + uuid + "] request scope bean close:" + this );
}
}
package hello.core.web;
import hello.core.common.MyLogger;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final MyLogger myLogger;
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request){
String requestURL = request.getRequestURI().toString();
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
logDemoService.logic("testId");
return "OK";
}
}
스코프와 Provider
➡️ Provider를 사용해 해결
🔸myLoggerProvider.getObject() 호출 시 점까지 빈의 호출 지연
private final ObjectProvider<MyLogger> myLoggerProvider;
private final ObjectProvider<MyLogger> myLoggerProvider;
스코프와 프록시
➡️ proxyMode = ScopedProxyMode.TARGET_CLASS 옵션 추가
🔸CGLIB라는 라이브러리로 내 클래스를 상속 받은 가짜 프록시 객체를 만들어서 주입
🔸이 프록시 객체는 실제 요청이 오면 그때 내부에서 실제 빈을 요청하는 위임 로직을 가지고 있음
🔸덕분에 클라이언트는 마치 싱글톤 빈을 사용하듯 편리하게 request scope 사용 가능
🔸Provider와 마찬가지로 진짜 객체 조회를 필요한 시점까지 지연 처리
🔸결국은 싱글톤과 다르게 동작하기 때문에 주의해서 사용해야 함.
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyLogger {
* 김영한님의 스프링 핵심 원리 - 기본편을 요약 및 정리한 내용입니다 *
'언어 > - Spring' 카테고리의 다른 글
[ 빈 스코프] 빈 스코프란? / 프로토타입 스코프 (0) | 2025.04.01 |
---|---|
[ 빈 생명주기 콜백 ] 빈 생명주기 콜백 시작 ~ 애노테이션 @PostConstruct,@PreDestroy (0) | 2025.03.27 |
[ 의존관계 자동 주입 ] 조회한 빈이 모두 필요할 때(List, Map) / 자동, 수동의 올바른 실무 운영 기준 (0) | 2025.03.26 |
[ 의존관계 자동 주입 ] 조회 빈이 2개 이상 / @Autowired 필드 명, @Qualifier, @Primary / 애노테이션 직접 만들기 (0) | 2025.03.26 |
[ 의존관계 자동 주입 ] 다양한 의존관계 주입 방법 / 옵션 처리 / 생성자 주입을 선택해라! / 롬복과 최신 트렌드 (0) | 2025.03.20 |