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

백엔드해야지님의 프로필 이미지
백엔드해야지

작성한 질문수

스프링 핵심 원리 - 기본편

[섹션6.중복 등록과 충돌] 동일 이름의 빈 수동, 자동 등록시 오버라이딩 관련하여

해결된 질문

작성

·

279

·

수정됨

0

안녕하세요. 질문이 생겼습니다.

 

  • 강의: 섹션6. 중복 등록과 충돌

  • 내용:

    • 3분 50초: "동일 이름의 빈이 자동, 수동 등록될 경우 수동등록을 우선하여 오버라이딩한다."

      • AutoAppConfig.java에서 수동 빈 등록 메서드에 오타를 내어 반환 타입을 MemberRepostitory 대신 MemoryMemberRepository로 설정하였습니다.

         

        @Configuration
        @ComponentScan(
        //        basePackages = "hello.core.member",
        //        basePackageClasses = AutoAppConfig.class,
                excludeFilters = @ComponentScan.Filter(type= FilterType.ANNOTATION, classes = Configuration.class)
                // AppConfig가 등록되지 않도록 제외시킴.
        )
        public class AutoAppConfig {
            @Bean(name = "memoryMemberRepository")
            public MemoryMemberRepository memberRepository() { // 오타부분
                return new MemoryMemberRepository();
            }
        }
        • 이 경우 AutoAppConfigTest실행시에 overriding 관련 로그가 없습니다.

        • 스프링 부트를 실행해도(CoreApplication 실행) 에러가 발생하지 않습니다.

      • 질문

        • 1) 같은 이름으로 같은 타입의 객체가 빈 등록되는데 오버라이딩되지 않으면 어떻게 된 것인지

        • 2) 이 상황에서 빈 수동 등록 메서드의 반환형이 어떤 영향을 미친건지

 

감사합니다.

답변 2

3

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

안녕하세요. 백엔드해야지님

이렇게 반환하는 타입을 구체적은 타입으로 지정하게 되면

@Component에서 사용하는 타입도 MemoryMemberRepository가 되고,

@Bean으로 등록하는 타입도 MemoryMemberRepository가 됩니다.

둘의 반환 타입까지 완벽히 똑같은 것이지요.

이 경우 타입에 빈의 이름까지 완전히 똑같기 때문에 빈의 정의를 오버라이딩 할 것이 없습니다.

이것은 마치 똑같은 빈이 두 번 컴포넌트 스캔 된 것과 같습니다. 이 경우 하나의 빈만 등록됩니다.

그리고 수동으로 등록한 빈이 우선순위를 가지게 됩니다.

감사합니다.

안녕하세요, 선생님. 먼저 답변 감사합니다.

 

달아주신 답변에서 제가 이해한 내용은

  • 빈 등록시 타입의 구분은 자동 빈 등록시에는 어노테이션이 붙은 구체 타입을, 수동 등록시에는 메서드 반환 타입을 이용한다.

  • 오버라이딩은 같은 빈 이름으로 다른 타입의 객체가 등록되는 상황에 해당되고, 같은 타입의 객체가 등록되는 상황은 오버라이딩으로 취급되지 않는다.

위 내용이 맞을까요?

 

시간 할애해주셔서 감사합니다.

 

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

네 맞습니다 :)

1

안녕하세요, 인프런 AI 인턴입니다.
백엔드해야지님의 질문에 대해 답변드리겠습니다.

  1. 같은 이름의 빈이 자동, 수동으로 등록될 때 스프링 부트 버전에 따라 다르게 작동할 수 있습니다. 스프링 부트 2.1 이하 버전에서는 수동 등록된 빈이 자동 등록된 빈을 오버라이딩했지만, 스프링 부트 2.1 이후 버전부터는 이러한 빈 등록 오버라이딩이 기본적으로 허용되지 않습니다. 오버라이딩이 일어나지 않았다면 스프링 부트의 버전을 확인하고 해당 설정을 확인해보셔야 합니다. spring.main.allow-bean-definition-overriding=true 옵션을 통해 오버라이딩을 허용할 수 있습니다.

  2. 메서드의 반환 타입이 실제 등록되는 빈 타입과 다르면 문제가 될 수 있지만, 여기서는 MemberRepository 인터페이스 타입의 구현체인 MemoryMemberRepository를 반환하므로 문제가 없습니다. 빈 수동 등록 메서드의 반환형은 스프링 컨테이너가 관리할 빈 객체의 타입을 결정하는데, 여기서 MemoryMemberRepositoryMemberRepository의 구현체이므로 인터페이스 타입으로 알맞게 등록됩니다.

오버라이딩과 관련된 로그가 없는 경우에는 빈 등록 과정에서 memoryMemberRepository라는 이름의 빈이 다른 설정으로 인해 덮어쓰기 되지 않았거나, 오버라이딩이 허용되지 않도록 설정되어 있을 수 있습니다. 이 경우에는 ApplicationContext에서 빈을 조회할 때 어떤 빈이 실제로 등록되었는지 확인할 필요가 있습니다.

해당 내용에 대한 자세한 설명이 필요하시면, 강의에 있는 Q&A 섹션을 활용하거나 강의를 다시 한번 확인해 보시는 것이 좋을 것 같습니다.

도움이 되셨길 바랍니다.

안녕하세요, 답변 감사합니다.

빈 수동 등록 메서드의 반환형은 스프링 컨테이너가 관리할 빈 객체의 타입을 결정하는데

저는 수동 등록시에 메서드의 반환되는 객체의 타입이 빈 등록시에 이용되는 것으로 생각했는데 이 부분이 잘못됬던거군요.

시간 할애해주셔서 감사합니다.

백엔드해야지님의 프로필 이미지
백엔드해야지

작성한 질문수

질문하기