ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Web관련 Scope
    Spring 2023. 8. 22. 01:15
    728x90
    반응형

    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 : 웹 소켓과 동일한 생명주기를 가지는 스코프

    728x90
    반응형

    'Spring' 카테고리의 다른 글

    Spring HandlerMapping & Adapter, ViewResolver  (1) 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
Designed by Tistory.