본 게시글은 김영한님의 스프링 핵심 원리 기본편을 정리한 글입니다.
이전까지는 ObjectProvider를 사용하여 주입시점을 특정하여 DL을 통해 주입을 시켰는데 이번에는 스코프 프록시 방식을 활용하여서 해결을 해보자.
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyLogger{
}
선언은 다음과 같이 하게 된다. 근데 여기 proxyMode에 TARGET_CLASS
와 INTERFACES
를 선택하게 되면 다음과 같은 차이가 있다.
TARGET_CLASS: 적용 대상이 인터페이스가 아닌 클래스
INTERFACES: 적용 대상이 인터페이스
이번에는 클래스에 적용하므로 TARGET_CLASS
를 사용하게 되었다. 이렇게 사용할 경우 이제 다른 코드에 있는 ObjectProvider를 예전에 사용하였던 것처럼 다시 MyLogger로 사용을 한다.
@Service
@RequiredArgsConstructor
public class LogDemoService {
private final MyLogger myLogger;
public void logic(String id){
myLogger.log("service id = " + id);
}
}
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final MyLogger myLogger;
@RequestMapping("log-demo")
@ResponseBody
public void logDemo(HttpServletRequest request, HttpServletResponse response) throws IOException {
String requestURL = request.getRequestURL().toString();
System.out.println("myLogger = " + myLogger.getClass());
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
logDemoService.logic("testId");
response.getWriter().write("ok");
}
}
이렇게 진행을 하게 될 경우에는 이전 ObjectProvider를 활용한것처럼 실행이 된다. 그러면 차이점이 어떤걸까? 한 번 확인해보기 위해서 myLogger.getClass()
를 통하여서 출력물을 확인해보자.
여기보면 원래라면 practicecore.ptcore.common.MyLogger@53f73b40
이렇게 출력됬어야했는데 뒤에 $$EnhancerBySpringCGLIB$$8efa78fa
이렇게 뭔가가 추가됬는데? 이게 뭐지? 이것은 CGLIB라는 라이브러리로 내 클래스를 상속 받은 가짜 프록시 객체를 만들어서 주입을 해준다고 한다. 이게 어떻게 되는걸까?
일단 한 마디로하면 분신술 느낌이랄까? 가짜 클래스를 만들어서 임의로 일단 의존관계 주입을 시킨다. 그러면 우리가 필요로 할때만 딱 진짜 친구를 꺼내온다고 한다. 결론은 비장의 한 발을 준비하기 위해서 앞으로 가짜를 내보내고 진짜 불러질때만 진짜 객체를 불러온다.