ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
// 기존 `AppConfig.class`의 설정 정보를 가지고 만든 객체를 반환 !
위 코드에서 인터페이스인 ApplicationContext
를 스프링 컨테이너라 하고, 스프링 컨테이너는 XML 기반 혹은 애노테이션 기반의 자바 설정 클래스로 만들 수 있다.
❗ 스프링 컨테이너는
BeanFactory
,ApplicationContext
로 구분해서 이야기한다.
AppConfig.Class
를 구성 정보로 지정한다. AppConfig.Class
에서 클래스에 @Configuration
애노테이션을 붙여주여야 하며, 스프링 빈으로 등록할 메소드에 @Bean
애노테이션을 붙여준다.
스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해 스프링 빈으로 등록한다.
스프링 빈 이름은 메서드 이름을 사용하지만, @Bean(name="xxxxx")
를 통해 이름을 직접 부여할 수 있다.
❗ 스프링 빈 이름은 각기 다른 이름을 부여해야 한다.
그렇지 않으면 다른 빈이 무시되거나, 기존 빈을 덮어쓰게 되는 설정에 오류가 발생한다.
학습 예제의 의존관계를 나타낸 그림이다. 위의 의존관계처럼 스프링 컨테이너는 의존관계를 주입한다.
스프링 컨테이너에서 스프링 빈을 찾는 가장 기본적인 조회 방법
: ac.getBean(빈이름, 타입)
만약, 조회할 스프링 빈이 없다면 NoSuchBeanDefinitionException: No bean named 'xxxxx' available
예외가 발생한다.
스프링 컨테이너에서 특정 타입의 모든 스프링 빈을 조회 방법
: ac.getBeansOfType()
ac.getBean(xxxxx.class)
와 같이 조회시 같은 타입의 스프링 빈이 둘 이상이면 오류가 발생한다. 이때는 빈 이름을 지정해야 한다. 이는 권장하는 방법은 아니다.
상속 관계에 놓인 스프링 빈의 경우, 부모 타입으로 조회 시에 자식 타입도 함께 조회된다.
그렇기에 모든 자바 객체의 부모 타입인 Object
타입으로 조회 시, 모든 스프링 빈을 조회한다.
부모 타입으로 조회 시, 자식 타입 스프링 빈이 2개 이상일 경우에는 오류가 발생한다.
그렇기에 빈 이름을 함께 지정하여 조회해야 한다.
앞서 스프링 컨테이너는 BeanFactory
, ApplicationContext
로 구분해서 이야기한다고 설명했다.
BeanFactory
, ApplicationContext
는 무엇일까?
🖐️BeanFactory
: 스프링 컨테이너의 최상위 인터페이스이며, 스프링 빈을 관리하고 조회하는 역할을 담당한다.
또한, getBean()
을 제공한다.
🖐️ApplicationContext
: BeanFactory
기능을 모두 상속받아서 제공한다. 상속받아 사용하는 기능 외에 수 많은 부가기능을 제공한다.
BeanFactory를 직접 사용할 일은 거의 없으며, 부가기능이 포함된 ApplicationContext를 사용한다.
스프링 컨테이너는 다양한 형식의 설정 정보를 받아드릴 수 있게 설계되어 있다.
ex) 자바 코드, XML, Groovy 등
🖐️ 애노테이션 기반 자바 코드 설정
: 지금껏 우리가 해왔던 것으로, AnnotationConfigApplicationContext
클래스를 사용하여 자바 코드로 된 설정 정보를 넘길 수 있다.
🖐️ XML 설정
: 최근에 스프링 부트로 넘어오게 되면서 XML 기반의 설정은 잘 사용하지 않는다. 레거시 프로젝트들이 XML 기반으로 설정되어 있다. XML 기반의 설정의 큰 장점은 컴파일 없이 빈 설정 정보를 변경할 수 있다.
GenericXmlApplicationContext
클래스를 사용하여 XML 설정 파일을 넘길 수 있다.
스프링이 다양한 형식의 설정 정보를 지원하게 되는 중심에는 BeanDefinition
추상화가 있다.
BeanDefinition
은 빈 설정 메타정보로, @Bean
마다 하나씩의 메타정보가 생성된다.
애노테이션 기반 자바 코드 설정을 예로 BeanDefinition
을 살펴보자.
AnnotationConfigApplicationContext
는 AnnotatedBeanDefinitionReader
를 사용해서 AppConfig.class
를 읽고 BeanDefinition
을 생성한다.
BeanDefinition
을 직접 생성해서 스프링 컨테이너에 등록할 수 도 있지만, 사용 빈도 수가 적기에 스프링을 배워가면서 천천히 알아가보려 한다.
지금은 스프링이 다양한 형태의 설정 정보를BeanDefinition
으로 추상화하여 사용한다는 정도만 알아두자.
📌 본 포스트는 스프링 핵심 원리 - 기본편 통해 학습한 내용을 요약 및 정리한 것입니다.