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

코린코린님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

프로토타입 스코프

프로토 타입 스코프 강의 질문 있습니다.

작성

·

265

4

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

[질문 내용]
안녕하세요, 강의 내용 중에 이해가 가지 않는 부분이 있어 질문드리고자 질문 글을 작성했습니다.

@Scope("singleton")
    static class SingletonBean{
        @PostConstruct
        public void init(){
            System.out.println("SingletonBean.init");
        }

        @PreDestroy
        public void destroy(){
            System.out.println("SingletonBean.destroy");
        }

    }

 

안녕하세요, 강의 내용 중 이해가 가지 않는 부분이 있어 문의드리고자 글을 작성했습니다.

 

위의 코드는 싱글톤 스코프로 테스트 코드를 작성하는 강의 내용입니다. 제가 이해가 잘 되지 않는 부분은 테스트 코드에 어노테이션으로 싱글톤 스코프를 단 것이 어떻게 ComponentScan의 대상이 되는지 이해를 할 수 없어서입니다. 수업에서 Component Scan으로 읽어온다고 설명해주셔서 더 의문이 있습니다. 

 

앞에서 배웠을 때는 AutoAppConfig 같은 class를 따로 만든 후, 해당 클래스에 ComponentScan을 위한 값을 설정하고, 그 Scan을 바탕으로 @Component 어노테이션을 포함한 것들을 자동으로 Scan해서 빈을 등록하는 것으로 이해하고 있습니다.

 

하지만 위의 코드는 테스트 코드 자체에 어느 곳에도 ComponentScan이 들어가지 않았는데, 어떻게 ComponentScan으로 자동 빈이 등록되는 것인지 과정을 자세히 알려주실 수 있으실까요?

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);

강의 중에는 위의 코드에서 클래스 명을 직접 넣는 것 자체가 ComponentScan이라고 하신 것 같은데,  앞선 강의에서 @Configuration + @Bean을 직접 등록하거나, @ComponentScan을 직접 등록한 것과 비교했을 때 ApplicationContext를 만드는데 코드상 차이점이 없어 보입니다. 

 

혹여나 질문 내용이 잘 이해가 안되시면 피드백 주시면, 좀 더 내용을 보완해서 다시 한번 질문글 적겠습니다. 감사합니다.

답변 5

3

1. @ComponentScan 어노테이션이 달린 클래스가 없는데,  어디서부터 ComponentScan이 시작된 것으로 이해를 하면 될까요? 마지막에 말씀해주신 것처럼 ApplicationContext 생성 및 빈 등록 과정 중에서 빈으로 등록되는 것이지, 딱히 Component Scan은 아니라고 보면 될까요? 

=> 네, 맞습니다.

 

2. @Component를 달지 않아도, 파라메터로 직접 넘겨버리면 빈으로 등록된다는 것으로 이해를 해도 괜찮을까요?

AnnotationConfigApplicationContext(a.class, b.class, c.class)

 

그렇다면 여러 파라메터를 한번에 넘길 수 있는 것으로 알고 있습니다. 예를 들어 아래 코드와 같이 넘기면, 각 클래스에 대해 @Component 어노테이션을 스킵하고 각각을 빈을 등록가능하다고 보면 될까요?

=> @Component가 있든 없든 파라미터로 넘어온 것들은 빈으로 등록이 진행됩니다.

@Component를 달지 않아도 넘겨준 클래스에 대한 DI는 @Autowired로 정상 동작하는 것으로 보면 될까요?

=> 말씀하신 "넘겨준 클래스에 대한 DI"가 정확하게 무엇을 의미하는지 모르겠네요. 다른 클래스의 의존관계로 주입되는 것을 말씀하시는지, 의존관계를 주입받는 걸 말씀하시는지.

전자의 경우라면 가능하고 후자의 경우라면 경우에 따라 다릅니다.

후자의 경우 컴포넌트스캔 없이 ApplicationContext를 생성한다면, 생성시 파라미터로 넘겨준 클래스들의 의존관계 주입에 필요한 클래스들도 함께  파라미터로 넘겨져야 합니다.

2

정확히 저랑 같은 고민을 하셨네요 님 질문 덕에 잘 알아갑니다

2

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

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);

ApplicationContext를 생성하는 과정에서 파라미터로 넘어간 SingletonBean.class를 빈으로 등록하는 게 내부적으로 진행됩니다. (AnnotationConfigApplicatioContext 내부 코드를 따라가다 보시면 파라미터로 넘어온 것을 빈으로 등록하는 과정을 찾아보실 수 있습니다.)

강의 중에는 위의 코드에서 클래스 명을 직접 넣는 것 자체가 ComponentScan이라고 하신 것 같은데, 

=> ComponentScan은 스캔 대상 찾아 빈으로 등록하는 것입니다. 빈으로 등록하는 관점에서  ApplicationContext를 생성하는 과정 중에 SingletoneBean클래스가 빈으로 등록되므로 ComponentScan으로 말씀하신 것 같습니다.

.
감사합니다.

코린코린님의 프로필 이미지
코린코린
질문자

답변 주셔서 감사합니다. 답변 주신 것에 대해 의문점이 생기는 것이 있는데 몇 가지만 더 문의 드릴 수 있을까요? 

 

1. @ComponentScan 어노테이션이 달린 클래스가 없는데,  어디서부터 ComponentScan이 시작된 것으로 이해를 하면 될까요? 마지막에 말씀해주신 것처럼 ApplicationContext 생성 및 빈 등록 과정 중에서 빈으로 등록되는 것이지, 딱히 Component Scan은 아니라고 보면 될까요? 

 

 

2. ApplicationContext를 생성하는 과정에서 파라미터로 넘어간 SingletonBean.class를 빈으로 등록하는 게 내부적으로 진행됩니다.

→ @Component를 달지 않아도, 파라메터로 직접 넘겨버리면 빈으로 등록된다는 것으로 이해를 해도 괜찮을까요?

AnnotationConfigApplicationContext(a.class, b.class, c.class)

그렇다면 여러 파라메터를 한번에 넘길 수 있는 것으로 알고 있습니다. 예를 들어 아래 코드와 같이 넘기면, 각 클래스에 대해 @Component 어노테이션을 스킵하고 각각을 빈을 등록가능하다고 보면 될까요? @Component를 달지 않아도 넘겨준 클래스에 대한 DI는 @Autowired로 정상 동작하는 것으로 보면 될까요?

그럼에도 불구하고 @Component로 관리하는 것은 유지보수 관점에서 코드의 간결성 때문으로 이해를 하면 될까요? 

 

 

0

좋은 질문 감사합니다.

0

오 안그래도 이런 기능도 있구나 하면서 보고 있었는데 딱 좋은 질문 감사합니다.