인터페이스 타입 변수에 인터페이스가 담길 수 있나요?
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("애플리케이션 빈 출력하기")
void findApplicationBean(){
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
// 이부분 질문
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
//이하 생략..
}
}스프링 빈 중에서 애플리케이션 빈만 출력하는 예제입니다
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
위 코드에서 변수 beanDefinition 의 타입인 BeanDefinition는 인터페이스니까
ac.getBeanDefinition(beanDefinitionName)의 리턴 타입이 BeanDefinition의 구현체일 줄 알았는데
매서드를 따라가보니 제일 상위에서 map.get()이 리턴되는데 그 값이 구현체가 아닌
BeanDefinition인터페이스 자체가 리턴되더라구요
Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
BeanDefinition bd = beanDefinitionMap.get(String beanName)
bd 가 리턴되게 되어있음
즉 BeanDefinition 인터페이스 타입인 bd가 메서드를 타고 내려오면서 질문한 부분인
BeanDefinition beanDefinition 에 담기게 되는 걸로 확인이 되었는데
인터페이스에 구현체가 아닌 인터페이스가 담길 수 있나요?
아니면 제가 뭔가 잘못 알고있거나 잘못 확인한 걸까요?
답변 2
1
안녕하세요. pansakr님, 공식 서포터즈 David입니다.
디버깅 해보시면 아래와 같이 여러가지의 BeanDefinition 구현체가 beanDefinitionMap에 담겨있는 걸 확인할 수 있습니다.

감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
pansakr님께서 문의하신 내용은 AnnotationConfigApplicationContext의 getBeanDefinition 메서드 호출 시 반환되는 객체의 타입에 대한 질문으로 이해됩니다. 질문 주신 내용에서 BeanDefinition 타입의 객체가 어떻게 인터페이스 타입으로 반환될 수 있는지에 대한 혼동이 있는 것 같습니다.
먼저, BeanDefinition은 인터페이스입니다. 스프링 프레임워크에서는 이 인터페이스를 여러 클래스가 구현하고 있습니다. 예를 들어, RootBeanDefinition, ScannedGenericBeanDefinition 등이 이에 해당합니다. getBeanDefinition(String beanName) 메서드는 실제로는 BeanDefinition 인터페이스의 구현체를 반환합니다. 여기서 중요한 점은, beanDefinitionMap이 String을 키로, BeanDefinition 인터페이스의 구현체를 값으로 가지고 있다는 것입니다. 따라서, beanDefinitionMap.get(beanName)을 통해 반환받는 객체는 BeanDefinition 인터페이스를 구현한 어떤 클래스 객체일 것입니다.
BeanDefinition 인터페이스 타입의 변수에 구현체가 담기는 것은 자바에서 다형성의 일반적인 원리에 부합합니다. 인터페이스 타입으로 선언된 변수는 그 인터페이스를 구현한 어떤 클래스의 인스턴스도 참조할 수 있습니다. 이는 인터페이스가 하나의 계약이나 규격을 제공하고, 구현체가 그 규격을 실제로 구현한다는 점에서 출발합니다. 프로그래밍에서 이런 방식을 통해 높은 수준의 추상화와 유연성을 확보할 수 있습니다.
ac.getBeanDefinition(beanDefinitionName) 호출이 BeanDefinition 인터페이스를 반환한다고 보기보다는, 사실상 BeanDefinition 인터페이스를 구현한 어떠한 클래스의 인스턴스를 반환하는 것이며, 이를 BeanDefinition 타입의 변수에 할당하게 됩니다. 바로 이 점이 객체 지향 프로그래밍의 다형성을 활용하는 예시 중 하나입니다.
즉, BeanDefinition beanDefinition이라는 표현은 구현체를 담는데 문제가 없으며, 이는 자바의 다형성 원칙에 기반한 것입니다.
사실 관련하여 확인하고자 하시는 자세한 부분이 있다면, 아래 링크가 도움이 될 것 같습니다.
- AnnotationConfigApplicationContext 다형성
// 예시 코드
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
여기서 getBeanDefinition 메서드는 BeanDefinition 인터페이스의 구현체를 반환하며, 이를 인터페이스 타입 변수에 담는 것이 가능합니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
0
beanDefinitionMap이 String을 키로, BeanDefinition 인터페이스의 구현체를 값으로 가지고 있다고 하셨는데요
실제 코드를 확인해 봤더니 Map<String, BeanDefinition> beanDefinitionMap 으로
인터페이스의 구현체가 아닌 인터페이스 자체를 가지고 있었습니다.
그러면 beanDefinitionMap.get()의 결과는 BeanDefinition 인터페이스의 구현체가 아닌
BeanDefinition 인터페이스 자체가 되는것이 아닌가요?
그리고 beanDefinitionMap.get()의 값이 결국 메서드를 타면서 최종적으로 리턴되어지는데
그렇게 되면 위에 질문드렸던 것 처럼 BeanDefinition타입 변수에 인터페이스가 들어가게 되는것 같습니다.
연결된 메서드들 중 어느 부분에서 BeanDefinition의 구현체를 생성해 리턴하는지 알려주시면
이해해 도움이 될 것 같습니다.
사실 이 부분은 강의 진행에 큰 영향은 없는 부분 같지만, 찾다보니 궁금해서 질문드렸습니다..
구현체가 동적으로 정해질 때, 팩토리 기법을 사용하나요?
0
47
2
MemberService의 인터페이스를 왜 사용하는지 궁금합니다.
0
72
1
롬복 @Setter를 써야 하는 상황이 있는건가요?
0
87
1
빈 등록 메서드의 파라미터가 빈이 아니어도 되나요?
0
79
1
테스트 속도가 나중에 영향이 있을까요?
0
75
1
gradle 설정 안떠서 질문 남깁니다!
0
116
2
build.gradle로 프로젝트를 여는 이유
0
81
1
provider 사용하는 이유
0
85
1
다음 강의 뭘 들어야 할까요
0
123
2
프로토타입 빈, 직접 destroy 호출 안 할 경우
0
62
1
beanB
0
79
2
퀴즈다시풀기
0
63
1
Gradle로 바꿔도 오류가 똑같이 발생하네요 ㅠㅠ
0
90
2
"중복 등록과 충돌" 강의에서 강사님과 다른 에러가 발생합니다.
0
63
3
run 실행했는데 결과창이 이렇게 뜨네요 왜 그런건가요>
0
102
2
도메인의 정의?
0
57
1
ApplicationContext 질문입니다.
0
60
1
@Scope의 proxyMode를 사용할때 단위 테스트 방법
0
86
2
ai api 선정하기 관련 질문
0
115
2
생성자 자동주입 관련해서
0
60
1
생성자 직접 호출 vs 팩토리 메서드 패턴
0
93
2
Spring에서 SessionScope와 RequestScope는 함께 사용되나요?
1
63
1
12:25
0
74
2
appConfig.xml 오류
0
125
1





