오늘의하루

Spring Web관련 Scope 본문

Spring

Spring Web관련 Scope

오늘의하루_master 2023. 8. 22. 01:15

request

웹 요청이 들어오고 나갈때까지 유지 되는 스코프

  • 클라이언트 A가 요청하면 A전용 객체가 만들어지고 서비스에서 A 객체를 조회할 수있으며 응답으로 요청이 종료되면 해당 스코프의 객체는 소멸한다.
  • Prototype은 매번 새로운 객체를 만들지만 request는 요청이 들어오면 생성하고 응답하기 전까지 유지된다.
  • Prototype은 소멸전 콜백이 안되지만 request의 경우 소멸전 콜백이 가능하다.

문제. 서버 실행시에는 요청이 없기 때문에 request scope의 빈을 주입받을 수 없다.

만약 의존관계 주입시 request scope의 빈을 주입한다고 가정했을때 어떻게 해결할 수 있을까?

  1. ObjectProvider<T>를 이용하여 빈의 생성을 지연 시킬 수 있다.
@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();
		System.out.println("[" + uuid + "] requst scope bean create : " + this);
	}
	
	@PreDestroy
	public void close() {
		System.out.println("[" + uuid + "] requst scope bean close : " + this);
	}
}

@Service
@RequiredArgsConstructor
public class LogDemoService {

	private final ObjectProvider<MyLogger> myLoggerProvider;
	
	public void logic(String id) {
		MyLogger myLogger = myLoggerProvider.getObject();
        // logic 메소드를 호출할때 MyLogger 객체를 만든다.
		myLogger.log("service id = " + id);
	}

}
  1. scope의 옵션중 proxyMode를 사용하여 가짜를 주입시킨 후 요청이 들어오면 실제 객체를 찾아서 사용한다.
    • proxyMode = ScopeProxyMode.xxxx를 추가하면 된다.
    • 적용 대상이 클래스라면 TARGET_CLASS
    • 적용 대상이 인터페이스라면 INTERFACES
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
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();
		System.out.println("[" + uuid + "] requst scope bean create : " + this);
	}
	
	@PreDestroy
	public void close() {
		System.out.println("[" + uuid + "] requst scope bean close : " + this);
	}
}

@Service
@RequiredArgsConstructor
public class LogDemoService {

	private final MyLogger myLogger;
    // proxy 객체가 처음에 들어가고 이후 요청이 들어오면 실제 객체를 찾아서 사용한다.
	
	public void logic(String id) {
		myLogger.log("service id = " + id);
	}

}

위 두 방법의 핵심 아이디어는 객체 조회를 꼭 필요한 시점까지 지연처리한다는 것이다.

 

그 외 Scope

session : 웹 세션이 생성되고 종료될때까지 유지되는 스코프

application : 웹의 서블릿 컨텍스와 같은 범위로 유지되는 스코프

websocket : 웹 소켓과 동일한 생명주기를 가지는 스코프

'Spring' 카테고리의 다른 글

Spring HandlerMapping & Adapter, ViewResolver  (0) 2023.08.23
Web Server, WAS, Servlet 정리  (0) 2023.08.22
Spring Bean Scope  (0) 2023.08.21
Spring Bean 생명 주기 콜백  (0) 2023.08.21
Spring 의존 관계 주입 정리  (0) 2023.08.21
Comments