이 글은 강의 : 김영한님의 - "스프링 핵심원리 - 기본편"을 듣고 정리한 내용입니다. 😁😁
ObjectProvider를 사용하도록 코드 수정
생성되지 않은 myLogger 의존관계 주입으로 문제가 되었던 LogDemoController 와 LogDemoService의 코드를 ObjectProvider 를 주입받도록 코드를 수정한다.
package hello.core.web;
import hello.core.common.MyLogger;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
// MyLogger 가 잘 작동하는지 확인하는 테스트용 컨트롤러
@Controller
@RequiredArgsConstructor // 자동 생성자 주입
public class LogDemoController {
private final LogDemoService logDemoService;
private final ObjectProvider<MyLogger> myLoggerProvider; // myLogger 를 찾을 수 있는 ObjectProvider 주입
// log-demo 요청이 오면 웹 브라우저에 데이터를 문자로 반환
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request) throws InterruptedException {
// HttpServletRequest: 클라이언트 요청 정보
String requestURL = request.getRequestURL().toString(); // 클라이언트가 요청한 URL 반환
// ObjectProvider로 myLogger 조회(DL)
MyLogger myLogger = myLoggerProvider.getObject();
myLogger.setRequestURL(requestURL); // myLogger 의 requestURL 에 값 저장
//myLogger.log("LogDemoController-MyLogger : " + myLogger);
myLogger.log("controller test");
//Thread.sleep(1000);
logDemoService.logic("testId");
return "OK";
}
}
package hello.core.web;
import hello.core.common.MyLogger;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor // 자동 생성자 주입
public class LogDemoService {
private final ObjectProvider<MyLogger> myLoggerProvider; // myLogger 를 찾을 수 있는 ObjectProvider 주입
public void logic(String id) {
// ObjectProvider로 myLogger 조회(DL)
MyLogger myLogger = myLoggerProvider.getObject();
myLogger.log("service id = " + id);
//myLogger.log("LogDemoService-MyLogger : " + myLogger);
}
}
CoreApplication main() 메서드 실행하면 웹 브라우저에 localhost:8080/log-demo 부분에서 제대로 OK가 출력 돼!
1) ObjectProvider 덕분에 ObjectProvider.getObject()를 호출하는 시점까지 스프링 컨테이너에 request 스코프 빈을 요청하는 것을 지연할 수 있다. (요청이 지연되므로 생성 역시 지연됨)
2) ObjectProvider.getObject()를 LogDemoController, LogDemoService 에서 각각 한번씩 따로 호출해도 같은 HTTP 요청이면 같은 스프링 빈(MyLogger)가 반환된다.
- 실제로 코드로 확인해보면, LogDemoController, LogDemoService에서 ObjectProvider.getObject()를 호출하여 조회한 MyLogger가 같은 인스턴스인 것을 확인할 수 있다.