728x90
/*
request 스코프의 생명 주기는 클라이언트의 요청이 발생하고 완료될 때까지 이다.
그런데 지금은, 요청이 없는 상태에서 어플리케이션을 실행했고, 다른 곳에서 DI를 요청하고 있다. Scope("request")가 활성화 되지 않았다.
즉, MyLogger 라는 bean이 존재하지 않는 상태에서 요청을 해버리니, 찾을 수 없다는 에러가 발생하는 것이다.
*/
@Scope(value = "request")
@Component
public class MyLogger {
}
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final MyLogger myLogger;


그렇다면, 어떻게 해결해야 할까?
ObjectProvider 을 사용 해보자
ObjectProvider 를 사용하면, DL(Dependency Lookup) 이 가능해진다.
이 말이 무엇인고 하니?
ObjectProvider 를 사용하면, 스프링 컨테이너에 빈을 요청하는 것을 지연할 수 있다.
(어플리케이션 실행 시, scope 의 생명주기로 인해 발생할 수 있는 에러를 회피할 수 있다.)
@Service
@RequiredArgsConstructor
public class LogDemoService {
private final ObjectProvider<MyLogger> myLoggerProvider;
public void logic(String id) {
MyLogger myLogger = myLoggerProvider.getObject();
myLogger.log("service id = " + id);
}
}
아.. 그런데 이렇게 하니, 되게 번거롭다.
또 다른 방법은 없을까?
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Component
public class MyLogger {
...
}
@Scope에 proxyMode 를 사용하면 ObjectProvider를 사용한 것 마냥 정상 작동 하는 것을 확인할 수 있다.
/*
proxyMode 를 설정하게 되면,
MyLogger 의 가짜 프록시 클래스를 만들어두고, HttpRequest와 관계 없이 가짜 프록시 클래스를 다른 빈에 미리 주입해둘 수 있게 된다.
코드 짧아짐. 퍄퍄
*/
예에전에 공부할 때 봤었던 내용 중
스프링 빈을 학습할 때,
일반 객체와 스프링 빈이 서로 다른 것을 확인할 수 있었다.
이것도 그렇다.
CGLIB 라이브러리로 클래스를 상속 받은 가짜 프록시 객체를 만들어 주입하게 된다.
myLogger = class hello.core_basic.common.MyLogger$$EnhancerBySpringCGLIB$$3f5a47b6
껍데기는 있으니, 처음에 생명 주기로 인한 에러는 발생하지 않게 되며,
객체의 기능이 호출될 때, 실제 객체(MyLogger)를 호출하여 동작하므로, 동작에도 문제가 없다.
참조자료
스프링 기본 (김영한)
728x90
'스프링' 카테고리의 다른 글
| JPA_N+1 문제 (0) | 2023.08.08 |
|---|---|
| Log를 (기본만) 알아보자 (1) | 2023.05.16 |
| @Qualifier 단점 - 컴파일 단계에서 오류가 안 잡힘. (0) | 2023.04.06 |
| @Qualifier 단점 - 컴파일 단계에서 오류가 안 잡힘. (0) | 2023.03.31 |
| DI는 생성자 주입으로 하자 (1) | 2023.03.30 |
댓글