• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

ApplicationContext 호출을 여러번하면 안되는건가요?

22.02.15 01:42 작성 조회수 322

0

=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
강의 내용은 문제 없이 싱글톤 유지가 잘 되는 것 확인하였습니다.
 
그런데 ApplicationContext를 2번 생성하면 bean의 생성자 메소드가 여러번 수행되길래, 아래 처럼 테스트 해봤는데 각각 다른 인스턴스가 반환이 됩니다.
 
//ac1.getBean 과 ac2.getBean 이 다름
ApplicationContext ac1 = new AnnotationConfigApplicationContext(AppConfig.class); ApplicationContext ac2 = new AnnotationConfigApplicationContext(AppConfig.class);
 
 
원래 이게 정상인가요??
 
그렇다면 등록한 bean을 A 클래스에서도 사용하고싶고 B 클래스에서도 사용하고 싶으면 어떻게 해야 되는지 궁금합니다.
 
 

답변 1

답변을 작성해보세요.

0

David님의 프로필

David

2022.02.15

안녕하세요. koon0312님, 공식 서포터즈 David입니다.

 

위와 같이 ApplicationContext를 2개 생성하여 사용하시면 서로 다른 환경을 구성하시는 것입니다.

즉, 두 ApplicationContext에서 각각 동일한 이름의 빈을 호출하면 참조 값이 다른 빈이 호출됩니다.

 

등록한 빈을 서로 다른 클래스에서 사용하고 싶으시다면 자동의존관계 주입을 받으시던지, ApplicationContext에서 getBean으로 (싱글톤 스코프를 가지는) 빈을 꺼내어 사용하고자 하는 클래스에 주입하셔야 합니다.

 

의존관계 자동 주입의 경우 컴포넌트 스캔, 의존관계 자동 주입 섹션 강의를 들어주세요.

 

감사합니다.

koon0312님의 프로필

koon0312

질문자

2022.02.15

답변 감사드립니다 :)

그런데 아직 이해가 안되는 부분이 있어 추가 질문 드리고 싶습니다.

 

ApplicationContext를 각각 호출하면 서로 다른 환경이 구성된다는 것은 이해했습니다.

getBean으로 빈을 직접 사용하고자 하는 클래스에 주입해야 한다는 것도 이해했습니다.

그런데 [등록한 빈을 서로 다른 클래스에서 사용하고 싶으시다면 자동의존관계 주입을 받으시던지,] 이 부분이 잘 이해가 안됩니다. (강의는 들었습니다)

 

자동의존관계 주입을 받더라도, 결국 ApplicationContext를 새로 호출하면 새로운 bean 인스턴스가 생성되는 것이 아닌가요?

방법론적인 측면보다는 실무에서는 통상적으로 어떤식으로 사용하게 되는지 궁금합니다.

ApplicationContext 혹은 Bean을 직접 다른 Class로 전달하며 사용하는 것이 일반적것이 맞는지 궁금하네요.

 

David님의 프로필

David

2022.02.15

자동의존관계 주입을 받더라도, 결국 ApplicationContext를 새로 호출하면 새로운 bean 인스턴스가 생성되는 것이 아닌가요?

=> ApplicationContext를 새롭게 호출해야 하는 상황이 어떤 상황일까요?

 

그렇다면 등록한 bean을 A 클래스에서도 사용하고싶고 B 클래스에서도 사용하고 싶으면 어떻게 해야 되는지 궁금합니다.

=>말씀하신 부분이 이런 상황 아니신가요? 등록한 빈(MemoryMemberRepository)를 MemberServiceImpl에서도 사용하고, OrderServiceImpl에서도 사용하고 있습니다.

koon0312님의 프로필

koon0312

질문자

2022.02.15

아래와 같은 경우를 예시로 작성해보았습니다.

- A와 B라는 메소드 각각 ApplicationContext를 호출했기 때문에 각각 다른 repository를 반환했습니다. 이 사실은 윗 답변을 통해 문제가 없는것임을 알게됐습니다.

- 아래 경우는 해결을 위해 ApplicationContext를 멤버변수로 쓰거나 파라미터로 넘겨주면 쉽게 해결이 되겠지만, Class단위로 분리되어있는 경우라면 어떻게 해결이 되어야 하는가, 에 대한 질문이었습니다. 

- 애초에 이러한 상황이 생기는 것은 설계가 잘못된 것인가 하는 의문도 있네요. 저의 경우에는 Bean에 등록한 컴포넌트를 각각 다른 Controller Class에서 싱글톤으로 사용하고 싶었습니다.

 

개념이 아직 부족해서 제가 제대로 질문을 하고있는지도 모르겠네요.ㅠㅠ 죄송합니다.

 

David님의 프로필

David

2022.02.15

제가 제대로 이해했다면 A, B, C 클래스가 있고

A, B, C 모두 빈으로 등록된 상태이고

A, B는 C를 주입 받는 관계인데

어떻게 C를 A, B에 각각 주입해줄 수 있느냐를 물으시는 것 같습니다. 맞을까요?

맞다면 컴포넌트 스캔, 의존관계 자동 주입 섹션 강의들을 들으시면 이 부분에 대해 해소하실 수 있습니다.

koon0312님의 프로필

koon0312

질문자

2022.02.15

이제 이해가 됐습니다, 제가 잘못된 생각을 하고 있었던것 같습니다, 감사합니다.

마지막으로 제가 이해한게 맞는지 확인 가능할까요?

  • 제가 오해했던점: 컴포넌트를 Bean으로 등록해놓으면 언제 어디서든지 ApplicationContext로 들고와서 사용하면 동일한 인스턴스가 반환될거라고 생각함.
  • 옳은방법: Bean에 등록된 컴포넌트를 받고싶은 클래스 또한 Bean으로 등록하여 의존관계를 주입시켜서 사용해야함. 
David님의 프로필

David

2022.02.15

1. 언제 어디서든지 ApplicationContext를 들고와서 사용하면 동일한 인스턴스가 반환됩니다. 다만, 위에서 언급하신 코드들은 이미 생성된 context를 들고 오는 게 아니라 ApplicationContext를 새롭게 생성하셨기 때문에 문제가 된 것입니다.

2. 빈으로 등록하지 않은 순수자바 클래스에서 빈을 수동으로 주입 받을 수 있습니다. 자동으로 의존관계를 주입받으려면 주입되는 것도, 주입받는 것도 모두 빈으로 등록되어 있어야 합니다.

 

많이 헷갈리신다면 본 강의를 반복하여 수강할 것을 권장드립니다.