request 스코프 관련 문의
143
작성한 질문수 2
안녕하세요, 몇가지 질문이 있습니다.
선생님의 코드대로 쳤는데 제 인텔리제이에서는 왜 다음과 같은 에러가 발생하는지 모르겠습니다.
왜 LogDemoController가 static 컨텍스트라고 떠서 이런 에러가 발생하는지 모르겠습니다.
제가 봤을땐 static이 아닌데 말이죠 (MyLogger, Controller, Service 모두 static은 없음)
여기까지의 소스 코드를 1차 첨부합니다. (에러 발생 코드)
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(value="request")
public class MyLogger {
private String uuid; // unique id
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 + "] " + "[" + requestURL + "] request scope bean create : " + this);
}
@PreDestroy
public void close(){
System.out.println("[" + uuid + "] " + "[" + requestURL + "] request scope bean close : " + this);
}
/*
로그를 출력하기 위한 클래스
request 스코프로 지정했으며, HTTP 요청당 하나씩 생성되고, HTTP 요청이 끝나는 시점에 소멸된다.
이 빈이 생성되는 시점에 자동으로 @PostConstruct 초기화 메서드를 사용해서 uuid를 생성해서 저장해둔다.
이 빈은 HTTP 요청 당 하나씩 생성되므로, uuid를 저장해두면 다른 HTTP 요청과 구분할 수 있다.
requestURL은 빈이 생성되는 시점에는 알 수 없으므로 외부에서 setter로 입력받는다.
*/
}package hello.core.web;
import hello.core.common.MyLogger;
import jakarta.servlet.http.HttpServletRequest;
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;
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final ObjectProvider<MyLogger> myLoggerProvider; // 스프링 컨테이너가 뜨면서 의존관계 주입을 해야하는데 mylogger는 request scope이라 아직 고객 요청이 없어서 에러
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request){
String requestURL = request.getRequestURL().toString(); // 고객이 요청한 url을 받을 수 있음
MyLogger myLogger = myLoggerProvider.getObject(); // 주입 시점에 주입 받을 수 있음
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
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;
public void logic(String id) {
MyLogger myLogger = myLoggerProvider.getObject();
myLogger.log("service id = " + id);
}
}어쨋든 이 문제를 해결하지 않으면 소스 코드 실행이 되지 않습니다. 따라서 intelliJ 가이드에 따라 static으로 만들어주고 실행을 하면 또 에러가 발생합니다.
private final ObjectProvider<MyLogger> myLoggerProvider;위 구문 초기화를 하라는 가이드에 = Null을 해주면
소스 코드 실행 시 (디버깅 결과) myLoggerProvider.getObject() 에서 널포인트 익셉션이 터집니다.
여기까지 상황의 코드를 2차 첨부합니다.
package hello.core.web;
import hello.core.common.MyLogger;
import jakarta.servlet.http.HttpServletRequest;
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;
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final ObjectProvider<MyLogger> myLoggerProvider; // 스프링 컨테이너가 뜨면서 의존관계 주입을 해야하는데 mylogger는 request scope이라 아직 고객 요청이 없어서 에러
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request){
String requestURL = request.getRequestURL().toString(); // 고객이 요청한 url을 받을 수 있음
MyLogger myLogger = myLoggerProvider.getObject(); // 주입 시점에 주입 받을 수 있음
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
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 static final ObjectProvider<MyLogger> myLoggerProvider = null;
public static void logic(String id) {
MyLogger myLogger = myLoggerProvider.getObject();
myLogger.log("service id = " + id);
}
}
어떻게 해결해야할까요? 제가 잘못 타이핑한 부분이 있다면 말씀 부탁드립니다.
답변 1
1
안녕하세요. 멍토님, 공식 서포터즈 y2gcoder입니다.
일단 먼저 1번 상태에서 사진을 보시면 LogDemoController의 멤버 변수인 LogDemoService logDemoService 가 사용되지 않아 회색인 것을 보실 수 있습니다!
package hello.core.web;
import hello.core.common.MyLogger;
import jakarta.servlet.http.HttpServletRequest;
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;
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final ObjectProvider<MyLogger> myLoggerProvider; // 스프링 컨테이너가 뜨면서 의존관계 주입을 해야하는데 mylogger는 request scope이라 아직 고객 요청이 없어서 에러
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request){
String requestURL = request.getRequestURL().toString(); // 고객이 요청한 url을 받을 수 있음
MyLogger myLogger = myLoggerProvider.getObject(); // 주입 시점에 주입 받을 수 있음
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
LogDemoService.logic("testId"); // 이 부분이 문제입니다!!
return "OK";
}
}그걸 토대로 LogDemoController를 살펴보시면
LogDemoService.logic("testId"); // 이 부분이 문제입니다!!이 부분에서 logDemoService.logic("testId") 로 부르지 않고 LogDemoService.logic("testId")로 부르고 있기 때문에 컴파일러는 너 왜 정적 메서드를 부르고 있냐? 이렇게 에러를 뱉어주고 있는 것으로 보입니다.
logDemoService.logic("testId")로 고치고 나서 다시 한 번 시도해보시겠습니까?
감사합니다.
구현체가 동적으로 정해질 때, 팩토리 기법을 사용하나요?
0
47
2
MemberService의 인터페이스를 왜 사용하는지 궁금합니다.
0
72
1
롬복 @Setter를 써야 하는 상황이 있는건가요?
0
87
1
빈 등록 메서드의 파라미터가 빈이 아니어도 되나요?
0
79
1
테스트 속도가 나중에 영향이 있을까요?
0
75
1
gradle 설정 안떠서 질문 남깁니다!
0
116
2
build.gradle로 프로젝트를 여는 이유
0
81
1
provider 사용하는 이유
0
85
1
다음 강의 뭘 들어야 할까요
0
123
2
프로토타입 빈, 직접 destroy 호출 안 할 경우
0
62
1
beanB
0
79
2
퀴즈다시풀기
0
63
1
Gradle로 바꿔도 오류가 똑같이 발생하네요 ㅠㅠ
0
90
2
"중복 등록과 충돌" 강의에서 강사님과 다른 에러가 발생합니다.
0
63
3
run 실행했는데 결과창이 이렇게 뜨네요 왜 그런건가요>
0
102
2
도메인의 정의?
0
57
1
ApplicationContext 질문입니다.
0
60
1
@Scope의 proxyMode를 사용할때 단위 테스트 방법
0
86
2
ai api 선정하기 관련 질문
0
115
2
생성자 자동주입 관련해서
0
60
1
생성자 직접 호출 vs 팩토리 메서드 패턴
0
93
2
Spring에서 SessionScope와 RequestScope는 함께 사용되나요?
1
63
1
12:25
0
74
2
appConfig.xml 오류
0
125
1





