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

임현강님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

탐색 위치와 기본 스캔 대상

AppConfig, ApplicationContext 에 대한 질문

작성

·

778

6

안녕하세요 강사님, 몇가지 질문 드리겠습니다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ-

질문 1.

제가 지금까지의 흐름을 맞게 이해하였는지 궁금합니다.

이전까지의 강의에서는(@ComponentScan 등장 전) AppConfig에서 @Configuration을 달았고,

@Configuration에 의해 그 밑에 있던 @Bean들을 조회하여 빈을 생성하고 등록하는 방식으로 진행이 됐습니다.

테스트 코드에서 
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
위 코드를 통해서 AppConfig의 빈이 등록될 수 있었고 

거기에서 @Configuration을 인식하여 그 안에 있는 @Bean들을 모두 인식해 필요한 빈들을 등록하였습니다.

결론적으로, 지금까지는 어떠한 컴포넌트 스캔도 이뤄지지 않았으며 모든 빈 등록은
new Annotation~~Context(AppConfig.class)에 의해 생성된 AppConfig 빈에 의해 이루어졌습니다.

제가 맞게 이해한건가요?

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

질문 2.

@ComponentScan을 사용한다면 ApplicationContext 가 굳이 필요없지 않나 하는 생각이 듭니다.

AppConfig와 @Configuration을 통해 수동으로 빈을 등록한다 하더라도.. 컴포넌트 스캔의 범위에 AppConfig를 두면 알아서 모든 빈들이 문제없이 생성될 것입니다.
(굳이 new Annotation~~Context(AppConfig.class) 를 통해 AppConfig 빈을 등록하지 알아도 알아서 스캔되어 등록될 테니까)

@Component, @Autowired를 통해 의존성 주입을 해결해도 컴포넌트 스캔의 범위만 잘 설정해준다면 모든 빈들은 문제없이 생성되고 주입될 것입니다.

그렇다면 실제 프로그래밍에서는 ApplicationContext는 쓰이지 않는다고 봐도 되나요?

아니면 강의에서 해오셨던 것처럼 테스트 코드에서 getBean을 사용하기 위해서만 사용된다고 보면 될까요?

그것도 아니면 실제 프로그래밍에서도 사용되는 어떠한 용도가 있을까요?

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
질문 3.

다른 질문에서 지금까지 CoreApplication을 전혀 사용하지 않았기 때문에 CoreApplication 없이 프로젝트를 돌려도 똑같이 돌아갈 것이라고 말씀하셨는데요.

CoreApplication에 대한 직접적인 사용은 없었지만 CoreApplication에 @SpringBootApplication이 있고
그 안에 @ComponentScan이 있고
CoreApplication은 hello.core 하위에 존재하니까 hello.core 하위의 패키지를 모두 컴포넌트 스캔 할 것이고.. 

그럼 CoreApplication은 컴포넌트 스캔으로 프로젝트에 영향을 미치고 있던 게 아닌가요?

어떻게 이 중요한 녀석을 빼놓고도 똑같이 동작할 수 있는 것인가요?

이에 대한 해답으로
new Annotation~~Context(AppConfig.class)를 통해 모든 빈 등록을 했으니 CoreApplication의 @ComponentScan이 없어도 되는 것인가? 라는 생각이 드는데요. 

만약 이게 맞다면 하나 더 궁금해지는 것이.. 

이대로라면 빈 등록이 CoreApplication의 @ComponentScan에 의해 한 번, AppConfig의 @Configuration에 의해 또 한 번. 총 두 번의 빈 등록이 일어나는데 이것에 의한 에러가 발생하지 않는 이유가 무엇인가요? 

이번 실습에서 이와 같은 오류를 막기 위해 @Configuration을 컴포넌스 스캔 범위에서 제외하는 코드를 따로 작성해줬던 것이 아니었나요?

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

질문 4.

이전 강의에서 스프링 컨테이너가 @Configuration을 통해 싱글톤을 가능하게 하는 방법을 설명해주셨는데요.
(@Configuration이 동록된 클래스를 상속받아 AppConFIg@@@CGLIB으로 사용하는 방법)

만약 AppConfig와 @Configuration이 없이 @ComponentScan을 통해서만 빈 등록과 의존성 주입을 모두 처리할 경우에는 어떤 식으로  싱글톤을 유지할 수 있게 되나요? 

혹시 이게 너무 지엽적인 부분이라면 "그냥 스프링 컨테이너가 알아서 잘 해준다." 정도로 받아들이고 넘어가도 괜찮을까요?

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 

지식의 소용돌이가 아직 완벽히 정리되질 않아 질문이 너무 길고 횡설수설 합네요. 죄송합니다.

강의 재밌게 잘 듣고 있습니다. 

감사합니다!

답변 6

6

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 현강님

질문에 답변들 바로 달아드릴게요.

질문 1.

네 이해하신 내용이 맞습니다.

질문 2.

이 부분을 햇갈리셨군요!

ApplicationContext가 바로 스프링 그 자체입니다.

ApplicationContext가 있어야 거기에서 @ComponentScan도 가능합니다.

@ComponentScan의 결과로 스프링빈을 스프링 컨테이너에 등록해야 하는데, ApplicationContext가 없으면 등록할 스프링 컨테이너 자체가 존재하지 않습니다. 쉽게 이야기해서 ApplicationContext가 본인의 스프링 컨테이너에 등록할 빈을 찾기 위해 @ComponentScan을 실행한다고 이해하시면 됩니다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
질문 3.

지금까지 CoreApplication은 단순히 코드만 존재한 것이고 해당 기능을 전혀 사용하지 않았습니다. 따라서 해당 코드를 완전히 삭제해도 동일하게 동작합니다.

CoreApplication을 통해 동작하려면 해당 클래스의 main()을 호출하거나 또는 테스트에서 @SpringBootTest처럼 스프링 부트와 통합하는 테스트를 진행해야 하는데요. 지금까지 전혀 그런 부분이 없었습니다^^!

참고로 CoreApplication을 사용하면 스프링 부트가 내부에서 생성하는 ApplicationContext를 사용하게 됩니다. 우리는 이런 스프링 부트를 사용하지 않고, 직접 스프링 코어인 ApplicationContext를 생성하고 사용하는 방법을 학습한 것입니다.

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

질문 4.

항상 ApplicationContext가 있어야 합니다. 그래야 여기에 스프링 빈이 보관됩니다^^!

화이팅!

1

임현강님의 프로필 이미지
임현강
질문자

감사합니다!!

1

김영한님의 프로필 이미지
김영한
지식공유자

네 맞습니다^^

사실 너무 중요한 부분이어서 잘 질문해주셨습니다.

0

감사합니다

0

좋은 질문 감사합니다. 잘 정리하고 갑니다! 

0

임현강님의 프로필 이미지
임현강
질문자

답변 감사합니다.

그럼 테스트 코드에 작성한 ApplicationContext가 없었으면  프로젝트가 아예 동작조차 하지 않았겠네요.

질문이 너무 길었는데 하나하나 읽어주시고 답변해주셔서 감사합니다.