
Inner Class를 Bean으로 등록할 수 없는 경우
public class OuterClass {
@Component
class InnerClass {
}
}
스프링 프로젝트 내부에 위와 같이 선언한 이너 클래스가 있습니다. 이너 클래스에 @Component를 붙여서 Bean으로 등록하려 하면 과연 Bean으로 등록이 잘 될까요?
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringNestedClassBeanApplication {
public static void main(String[] args) {
ConfigurableApplicationContext ac = SpringApplication.run(SpringNestedClassBeanApplication.class, args);
OuterClass.InnerClass innerClass = ac.getBean(OuterClass.InnerClass.class);
System.out.println("innerClass = " + innerClass);
}
}
확인을 위해 ApplicationContext에서 getBean() 메서드를 통해 InnerClass의 Bean을 가져와서 print하도록 해보았습니다.

코드를 실행해보면, NoSuchBeanDefinitionException이 발생하며 InnerClass Bean을 찾을 수 없다고 합니다.
Inner Class를 Bean으로 등록할 수 있는 경우
import org.springframework.stereotype.Component;
@Component // 추가
public class OuterClass {
@Component
class InnerClass {
}
}
이번에는 OuterClass에도 @Component를 달아서 OuterClass, InnerClass 둘 다 Bean으로 등록한 뒤 코드를 실행해보겠습니다.

이번에는 Bean이 조회가 되어 정상적으로 출력이 된 모습을 확인할 수 있습니다.
왜 OuterClass를 Bean으로 등록하지 않으면 InnerClass를 Bean으로 등록할 수 없을까?
기본적으로 InnerClass는 OuterClass의 인스턴스가 없이는 객체 생성이 불가능합니다.

따라서 스프링 컨테이너 초기화 시점에 컴포넌트 스캔 대상의 클래스들을 읽어 Bean으로 등록할 클래스들은 인스턴스를 생성한 뒤 컨텍스트에 등록하여 싱글톤으로 관리해야 하지만, OuterClass의 인스턴스가 없으면 InnerClass의 인스턴스를 생성할 수 없기 때문에 Bean으로 등록할 수 없습니다.
이러한 이유로, OuterClass를 Bean으로 등록하면, OuterClass의 인스턴스를 통해 InnerClass의 인스턴스도 생성할 수 있기 때문에
이런 경우에는 InnerClass를 Bean으로 등록할 수 있게 됩니다.
또한 중첩 클래스를 static으로 선언하면 OuterClass 없이 인스턴스를 생성할 수 있기 때문에 이 경우에도 중첩 클래스를 Bean으로 등록할 수 있게 됩니다.
참고로 중첩 클래스(Static Nested Class)와 이너 클래스(Non-Static Nested Class)는 다른 개념이긴 합니다.
import org.springframework.stereotype.Component;
public class OuterClass {
@Component
static class StaticNestedClass {
}
}
@SpringBootApplication
public class SpringNestedClassBeanApplication {
public static void main(String[] args) {
ConfigurableApplicationContext ac = SpringApplication.run(SpringNestedClassBeanApplication.class, args);
OuterClass.StaticNestedClass staticNestedClass = ac.getBean(OuterClass.StaticNestedClass.class);
System.out.println("staticNestedClass = " + staticNestedClass);
// staticNestedClass = com.devchw.springnestedclassbean.OuterClass$StaticNestedClass@5922d3e9
}
}
물론 개발을 하면서 InnerClass를 Bean으로 등록해서 사용할 일은 거의 없습니다만..(한번도 본 적 없음) 다시한번 스프링의 핵심 원리에 대해서 생각하게 되어 개인적으로 좋은 주제라고 생각이 되어 글로 정리해보게 되었습니다.
예제에 쓰인 모든 코드는 깃허브 에서 확인하실 수 있습니다.
감사합니다.
참고자료
'개발 > Spring' 카테고리의 다른 글
Spring RestDocs 개선기(2) - 리플렉션을 이용한 Enum 문서 작성 자동화 (1) | 2025.01.29 |
---|---|
Spring RestDocs 개선기(1) - 커스텀 스니펫적용 + Enum 값 확인 UX 개선 (1) | 2025.01.29 |
예제 코드로 알아보는 Spring RestDocs (6) | 2024.11.13 |
로그추적기 - 3. 필드동기화 (0) | 2023.08.17 |
로그추적기 - 2. 파라미터로 동기화 (0) | 2023.08.17 |
개발을 하며 만났던 문제들과 해결 과정, 공부한 내용 등을 기록합니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!