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

박동규님의 프로필 이미지
박동규

작성한 질문수

스프링 핵심 원리 - 기본편

컨테이너에 등록된 모든 빈 조회

AnnotationConfigApplicationContext 다형성

작성

·

249

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)


2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)


3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)



[질문 내용]
강의 내용에서 MemberApp과 OrderApp에는 다음과 같이

// MemberApp.java

package hello.core;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MemberApp {
    public static void main(String[] args) {
//        AppConfig appConfig = new AppConfig();
//        MemberService memberService = appConfig.memberService();

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);

        Member member = new Member(1L, "memberA", Grade.VIP);
        memberService.join(member);

        Member findMember = memberService.findMember(1L);
        System.out.println("new member = " + member.getName());
        System.out.println("find Member = " + findMember.getName());
    }
}

// OrderApp.java

package hello.core;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.order.Order;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class OrderApp {
    public static void main(String[] args) {

//        AppConfig appConfig = new AppConfig();
//        MemberService memberService = appConfig.memberService();
//        OrderService orderService = appConfig.orderService();

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        OrderService orderService = applicationContext.getBean("orderService", OrderService.class);

        Long memberId = 1L;
        Member member = new Member(memberId, "memberA", Grade.VIP);
        
        memberService.join(member);

        Order order = orderService.createOrder(memberId, "itemA", 20000);

        System.out.println("order = " + order);
        System.out.println("order.calculatePrice() = " + order.calculatePrice());

    }
}

applicationContext를 생성할 때 그 자료형을 ApplicationContext란 Interface로 선언했는데 왜 ApplicationContextInfoTest에서는 ac의 자료형을 AnnotationConfigApplicationContext으로 하신거죠?

 

// ApplicationContextInfoTest.java

package hello.core.beanfind;

import hello.core.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationContextInfoTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("모든 빈 출력하기")
    void findAllBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + " object = " + bean);
        }
    }

    @Test
    @DisplayName("애플리케이션 빈 출력하기")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);
        }
    }
}

그리고 ac의 자료형을 ApplicationContext 로 했을 때는 findApplicationBean 메서드의 ac.getBeanDefinition이 사용할 수 없다고 나오는데 AnnotationConfigApplicationContext으로 선언했을 때는 사용할 수 있는데 그 이유가 뭔지 궁금합니다.

답변 1

0

안녕하세요. 박동규님, 공식 서포터즈 OMG입니다.

 

ApplicationContext 인터페이스는 다음과 같은 코드로 되어있는데요,

imageAnnotationContext 인터페이스가 extends한 인터페이스 항목에는 getBeanDefinition 에 대한 정의를 가진 인터페이스가 존재하지 않습니다.

반면, 구체타입인 AnnotationConfigApplicationContext클래스의 경우

아래와 같은 상속 구조로 인해 getBeanDefinition()을 호출할 수 있습니다.


 

아래에서 제가 확인한 것을 직접 코드 구조를 따라가서 확인해보시면 좋을 것 같아요.

(코드 내 클래스 이름에 마우스 커서를 올리고 Window : ctrl + 왼쪽 클릭 / Mac:command+ 왼쪽 클릭)


 

AnnotationConfigApplicationContext 클래스

image

GenericApplicationContext 클래스

imageimage

BeanDefinitionRegistry 인터페이스

image

정리하면, ApplicationContextInfoTest.java 에서 아래의 코드를 사용하려면, 인터페이스 타입의 ApplicationContext가 아닌 구체타입의 클래스(AnnotationConfigApplicationContext)를 사용해야하기 때문에 사용한 것입니다.

image

 

감사합니다.

박동규님의 프로필 이미지
박동규

작성한 질문수

질문하기