강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

ttimotti님의 프로필 이미지
ttimotti

작성한 질문수

토비의 스프링 부트 - 이해와 원리

스프링 컨테이너로 통합

WebApplicationContext를 DispatcherServlet에 this로 넘기는 것

작성

·

239

·

수정됨

0

 안녕하세요.
스프링 강의 먼저 듣고 부트 강의를 듣고 있습니다.
이번 강의에서 초반에는 this가 아니라 applicationContext 변수를 넘겼기 때문에 변수의 타입에 Web을 추가해서 넘겨줬었는데요.
후반에는 this로 GenericWebApplicationContext를 넘겨주니까 applicationContext 변수의 타입은 다시 GenericApplicationContext로 하는 것도 괜찮은 방법일까요? 확인해보니까 registerBean 메서드는 GenericApplicationContext의 메서드여서 질문드려봅니다.
해당 클래스는 인터페이스 클래스가 아니어서 뭘 써도 상관이 없는걸까요?

답변 2

1

토비님의 프로필 이미지
토비
지식공유자

어느 수업의 어느 시점에 나오는 예제인지를 알려주시면 좀 더 정확하게 답을 드릴 수 있을 것 같습니다.

ApplicationContext 인터페이스로 대표되는 스프링 컨테이너는 사실 굉장히 복잡하고 깊은 여러 인터페이스와 클래스 상속 구조를 가지고 있습니다. 어떤 방식으로 스프링의 구성 정보를 전달하는가에 따라서 실제 사용되는 클래스가 달라지죠.

그런데 예제와 같이 스프링의 기능을 살펴볼 때는 필요한 기능을 가진 가장 최상위 인터페이스 또는 클래스를 사용해서 코드를 만듭니다. 일반적인 스프링 개발에선 사실 이 ApplicationContext를 구현한 스프링 컨테이너를 직접 액세스할 경우는 거의 없습니다. 다만 강의에서는 동작원리를 살펴보기 위해서 적절한 타입으로 만들어진 스프링 컨테이너를 받아서 사용하고 있죠.

ApplicationContext로 대표되는 스프링 컨테이너 오브젝트가 웹과 관련된 컨텍스트에서 사용될 때는 꼭 Web이 들어간 ApplicationContext를 사용해야 합니다. DispatcherServlet 등에서 사용하는 메소드를 가지고 있어야 하거든요. 그래서 GenericWebApplicationContext 타입을 썼을텐데, 결국 이것도 상위는 GenericApplicationContext 혹은 가장 최상위 ApplicationContext를 구현한 것이기 때문에, 만약 코드에서 사용하는 기능이 getBean()과 같이 가장 단순한 거라면 ApplicationContext로, registerBean() 처럼 코드로 빈을 등록하는 작업이 필요한 경우라면 이 메소드를 가진 상위 타입인 GenericApplicationContext로 받아서 사용할 뿐입니다.
일단 강의에서는 스프링 컨테이너가 이런 작업을 하고 있구나 정도만 이해하시면 충분합니다. 그때마다 쓰이는 클래스나 인터페이스 타입이 다르긴 하지만 결국 이게 우리가 개발할 때 만들어지는 스프링 컨테이너가 구현하거나 상속한 인터페이스나 클래스 중의 하나일 것이라고 생각하시면 충분할 것 같습니다.

내부 구조가 더 궁금하시다면 스프링 소스 코드에서 ApplicationContext 인터페이스로부터 출발해서 이를 확장한 여러 인터페이스, 그리고 이를 구현한 각종 클래스를 살펴보시면 됩니다. 흥미롭긴하지만 사실 스프링을 더 깊이 이해하는데 크게 도움이 될 것은 아니라서, 그 부분을 자세히 보여드리면서 설명드리진 못했네요.

말씀하신 것처럼 예제 코드에서 필요로 하는 메소드를 가지고 있는 타입이라면, 그 타입으로 받아서 사용해보세요. 좀 특별한 케이스를 제외하면 잘 변환이 될 겁니다. 코드를 변경하고 컴파일과 동작이 잘 되면 아무 문제가 없는 것입니다.

혹시 더 궁금하신 게 있으시면 보고 계신 코드를 포함해서 다시 질문을 해주세요. 감사합니다.

ttimotti님의 프로필 이미지
ttimotti
질문자

강의 중에 질문한 내용이라 해당 강의에 링크가 되어있는 줄 알았습니다.

질문드렸던 부분은 [섹션 5의 디스패쳐 서블릿으로 전환] 6:12 부분입니다.

인터페이스의 구현체인 경우에만 인터페이스 타입으로 받아올 수 있는 것인지, 인터페이스가 아니어도 상속 받은 클래스라면 상위 클래스 타입으로 받아와도 되는 것인지가 궁금했습니다.

강의에서는 인터페이스의 구현체가 아닌 상속 받은 클래스 이기 때문에 그대로 사용한 것인가 해서요.
컴파일과 동작이 잘 되면 상위 타입으로 받아와도 상관은 없지만, 반드시 상위 타입으로 받아올 필요는 없다는 말씀이실까요? 지금까지는 가능하면 상위 타입으로 받아오는 게 여러가지 측면에서 더 낫다고 이해하고 있었습니다.

 

 

그리고

스프링 소스 코드에서 ApplicationContext 인터페이스로부터 출발해서 이를 확장한 여러 인터페이스, 그리고 이를 구현한 각종 클래스를 살펴보시면 됩니다

이런 생각은 못해봤는데, 앞으로의 공부에 도움이 많이 될 것 같습니다. 감사합니다.

토비님의 프로필 이미지
토비
지식공유자

질문 상단 좌측의 삼각형 화살표 부분을 누르면 질문하신 시점의 수업으로 이동하는군요. 처음 알았습니다. 😅

 

가능하면 대표되는 인터페이스로 받는 것이 일반적이지만 ApplicationContext의 특별한 구현 기능(메소드)이 필요할 때는 구현 클래스로 받는 경우도 많습니다.

ttimotti님의 프로필 이미지
ttimotti
질문자

그냥 컨트롤러 서비스 레포지토리만 쓰면서 개발하는 주니어인데, 토비님 덕분에 회사에서 숨통이 좀 트입니다. 감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.
ttimotti님, 질문 주셔서 감사합니다.

질문하신 내용에 대한 이해를 돕기 위해 다음과 같은 설명을 드리겠습니다.

스프링 프레임워크에서 DispatcherServletWebApplicationContext와 밀접하게 연관되어 있습니다. GenericWebApplicationContext는 기본적으로 일반적인 ApplicationContext의 기능을 확장하고, WebApplicationContext는 웹 애플리케이션 전용 웹 관련 기능을 추가 제공합니다.

  • 초반에는 this 대신 applicationContext 변수를 사용하여 Web 타입을 추가했다는 것은, WebApplicationContext의 특화된 기능이 필요한 상황이었기 때문일 것입니다. 이때는 웹 환경에서 부가적인 기능과 설정, 예를 들어 ServletContext와의 통합 등이 필요했을 수 있습니다.

  • 후반에서 thisGenericWebApplicationContext로 넘기는 것은 주요 목적이 그 환경에서 일반적인 스프링 빈 관리의 기능만으로 충분하다는 판단 때문일 것입니다. 또한, registerBean 메서드가 GenericApplicationContext에서 제공되는 만큼, 이를 사용하는 데 문제가 없을 것입니다.

따라서, applicationContext 변수의 타입을 GenericApplicationContext로 설정해도 특정 웹 컨테이너에 구애받지 않고 일반적인 스프링 컨텍스트 기능을 활용할 수 있게 됩니다. 다만, 웹 관련 부가 기능이 필요하지 않는 범위 내에서 설정하는 것이 좋습니다.

추가적으로, 관련된 질문과 답변을 통해 더 많은 정보를 얻으실 수 있습니다:
- 스프링 컨테이너 설명중 헷갈리는 부분이 있어 질문 드립니다.
- 독립 실행형 스프링 애플리케이션까지 본 수강생입니다. 질문있습니다.
- 안녕하세요 토비님. 강의중 질문있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

ttimotti님의 프로필 이미지
ttimotti

작성한 질문수

질문하기