작성
·
346
답변 1
0
지난 싱글톤 강의에서 @Configuration 이 싱글톤을 위해 존재한다고 하셨는데
다른 질문글에 대한 답변으로 @Configuration 과 싱글톤 방식은 연관이 없다고 하셔서 혼란스럽습니다..ㅠ
질문1.
@ComponentScan 을 이용해서 @Component가 붙은 클래스를 다 Bean으로 등록한다고 해주셨는데요. 스프링 어플리케이션을 실행한다고 하면 그냥 CoreApplication에 @ComponentScan 붙여도 되나요?
=> ComponentScan은 스프링 애플리케이션의 일부이지 전부는 아닙니다.
@SpringBootApplication 해당 애노테이션 내에 @ComponentScan이 포함되어 있습니다.
질문2.
AutoAppConfig에 @Configuration 을 붙인 이유는 뭔가요? AutoAppConfig클래스를 Bean으로 등록하기 위함인가요? 그렇다면 AutoAppConfig클래스를 왜 Bean으로 등록해야되나요?
=> @Configuration을 붙인 이유는 @Bean이 붙은 메서드를 통해 객체를 생성하려고 할 때 proxy를 통해 내부적으로 빈 목록을 먼저 찾아서 이미 생성된 빈이 있다면 이미 생성된 빈을 반환하고자 함입니다.
Configuration Class를 빈으로 등록하는 이유 중 하나는 빈으로 등록하여 사용할 때 스프링 컨테이너로부터 여러가지(자동 의존관계 주입과 같은 것들) 지원받을 수 있기 때문입니다. 사실 Configuration Class뿐만 아니라 다른 모든 것들에도 해당하는 말입니다.
답변 감사합니다. 제가 봤던 질문글은
https://www.inflearn.com/questions/157309 였습니다.
질문2의 답변에 대한 추가적인 질문을 드리고 싶습니다.
@Configuration을 붙인 이유는 이미 생성된 빈이 있다면 이미 생성된 빈을 반환하고자 함이라고 하셨는데요. 말씀하신 것을 다르게 말하면 싱글톤 때문이라고 저는 이해했습니다.
그런데 제가 읽었던 질문글의 영한님의 답변을 보면 스프링은 ComponentScan 시에 기본으로 싱글톤으로 빈을 등록한다고 하시는데요.
제가 읽어보기엔 말이 앞뒤가 잘 안맞게 느껴져서 혼란스럽습니다 ㅠㅠ
@Configuration
-> 강의에서 : 싱글톤 때문에 사용한다.
-> 질문글에서 : Configuration과 싱글톤은 관련 없다.
@ComponentScan
-> 질문글 중반 : @Configuration 없이 @Bean만 사용해서 스프링 빈을 등록해도 싱글톤으로 등록됩니다.
-> 질문글 후반 : 싱글톤이 안되고, 문제가 되는 부분은 @Bean으로 수동 등록할 때, 내부의 의존관계를 직접 메서드 호출로 주입할 때만 발생하고, 이때 문제를 해결해주는 것이 @Configuration 애노테이션입니다.
제가 무엇을 이해 못하고 있는걸까요?
@Bean으로 등록할때는 Configuration 어노테이션이 있어야 싱글톤이 된다는 것이고
@Component를 빈으로 등록할때는 Configuration 없이 ComponentScan 만 있으면 된다고 들려서요.
궁극적으로 왜 Configuration, ComponentScan을 같이 쓰는지 아직 잘 모르겠습니다.
@Configuration을 붙인 이유는 @Bean이 붙은 메서드를 통해 객체를 생성하려고 할 때 (내부 의존관계를 위해 직접 메서드 호출을 하게 되면) proxy를 통해 내부적으로 빈 목록을 먼저 찾아서 이미 생성된 빈이 있다면 이미 생성된 빈을 반환하고자 함입니다.
제가 위처럼 언급한게 질문자분께는 혼란스럽게 느껴질 수도 있다고 생각되네요.
빨간 색으로 하이라이트된 것을 추가해서 다시 보시면 이해가 조금 되실까요?
https://www.inflearn.com/questions/157309 영한님 답변
싱글톤이 안되고, 문제가 되는 부분은 @Bean으로 수동 등록할 때, 내부의 의존관계를 직접 메서드 호출로 주입할 때만 발생하고, 이때 문제를 해결해주는 것이 @Configuration 애노테이션입니다. 이 부분은 @Configuration과 싱글톤, 그리고 @Confiruation과 바이트코드 조작의 마법 부분을 다시 복습해보시길 바랍니다.
https://www.inflearn.com/questions/323589 제 답변
만약 @Configuration을 붙였다면 2-2과정에서 new Component2(component1())에서 component1()이 호출될 때 스프링 빈으로 등록하는 과정이 바로 시작됩니다. 그리고 빈을 등록하는 과정에서 동일한 이름으로 싱글톤 빈이 존재하는지 확인합니다. 이렇게 동작하는 이유는 @Configuration을 붙인 Config클래스는 실제 Config타입의 객체가 아닌 Config 타입을 상속하는 SpringCGLIB 객체이기 때문입니다. 따라서 @Configuration을 붙인 Config클래스에 @Bean이 붙은 메서드가 실행될 때는 필요한 의존관계가 있다면 빈이 존재하는지 찾고 없으면 생성하고, 있다면 가져와서 주입해줍니다. 그렇기 때문에 Component1 타입의 스프링 빈이 1개로 유지될 수 있는 것입니다.
제가 무엇을 이해 못하고 있는걸까요? @Bean으로 등록할때는 Configuration 어노테이션이 있어야 싱글톤이 된다는 것이고@Component를 빈으로 등록할때는 Configuration 없이 ComponentScan 만 있으면 된다고 들려서요.
=> 싱글톤처럼 사용되는 빈을 등록하는 것과 Configuration 애노테이션이 무관하다는 말입니다. 빈의 등록(생성)이 포인트 입니다.
위의 답변과 강의를 다시 천천히 들여다보시고 조금 정리하신 후에 다시 질문 부탁드려요:)
친절한 답변 감사합니다
ComponentScan을 하든 ApplicationContext ac = new AnnotatiedApplicationContext(AppConfig.class) 를 하든
빈의 등록 방식은 싱글톤이지만
Configuration 어노테이션을 사용해야지만 중복된 객체를 생성하지 않고 등록한 빈을 주입해준다는 것을 알았습니다 ㅎㅎ
현재, 인프런 답변등록 버그로 인해 답변등록 버튼 선택 후 작성한 답변이 실시간으로 노출되지 않습니
다. 아래 추가로 작성하신 부분은 삭제 부탁드립니다.
어떤 질문 글에서 위와 같은 언급을 하셨는지 링크 전달해주시면 답변에 도움이 될 것 같습니다.