1. [ Spring 컨테이너 생성]
스프링 컨테이너가 생성되는 과정은 아래와 같다
//스프링 컨테이너 생성
//예시로 AppConfig.class에 스프링에 대한 기본설정이 있다는 가정이다.
ApplicationContext applicationContext =
new AnnotaionConfigApplicationContext(AppConfig.class);
JavaScript
복사
•
ApplicationContext를 스프링 컨테이너라고 한다
•
ApplicationContext는 인터페이스다.
•
스프링 컨테이너는 XML을 기반으로 만들수 있고, 어노테이션 기반의 자바 설정 클래스로 만들 수 있다.
•
위에 사용한 AppConfig 를 사용했던 방식이 어노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만드는 것이다.
•
주로 자바설정 클래스 기반으로 스프링 컨테이너(ApplicationContext)를 만든다
◦
new AnnotaionConfigApplicationContext(AppConfig.class);
◦
이 클래스는 ApplicationContext 인터페이스 구현체이다
참고 : 더 정확히는 스프링 컨테이너를 부를 때 `BeanFactory`, `ApplicationContext` 로 구분해서 이야기한다. 일반적으로 ApplciationContext 를 스프링 컨테이너라고 한다.
2. [스프링 컨테이너의 생성과정]
•
new AnnotationConfigApplicationContext(AppConfig.class)
•
스프링 컨테이너를 생성할 때는 구성정보를 지정해줘야한다.
•
여기서는 AppConfig.class 를 구성 정보로 지정했다.
•
스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈으로 등록한다.
•
빈 이름은 메서드 이름을 사용한다.
•
빈 이름을 직접 부여할 수 도있다
◦
@Bean(name="memberService2")
주의 : 빈 이름은 항상 다른이름을 부여 해야한다. 같은 이름을 부여하면, 다른 빈이 무시되거나, 기존 빈을 덮어버리거나 설정에 따라 오류가 발생한다.
•
스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI) 한다.
•
단순히 자바코드를 호출하는 것 같지만, 차이가 있다.
참고
스프링 빈을 생성하고, 의존 관계를 주입하는 단계가 나누어져 있다. 그런데 이렇게 자바 코드로 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한번에 처리된다. 여기서는 이해를 돕기위해 개념적으로 나누어 설명했다.
정리
스프링 컨테이너를 생성하고, 설정(구성) 정보를 참고해서 스프링 빈도 등록하고, 의존관계도 설정했다.
3. [컨테이너의 등록된 모든 빈 조회 해보기 ]
스프링컨테이너에 실제 스프링 빈들이 잘 등록되었는지 확인해본다. 아래는 직접 작성한 코드를 따온 것이다.
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.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
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);
//BeanDefinition.ROLE_APPLICATION : 어플리케이션을 개발하기위해 등록한 빈들을 의미
//BeanDefinition.ROLE_INFRASTRUCTURE : 스프링 내부에서 사용하는 빈들을 의미
if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
Object bean = ac.getBean(beanDefinitionName);
System.out.println("name = " + beanDefinitionName + "Object = " + bean);
}
}
}
}
JavaScript
복사
•
모든 빈 출력하기
◦
실행하면 스프링에 등록된 모든 빈 정보를 출력 할 수 있다.
◦
`ac.getBeanDefinitionNames()` : 스프링에 등록된 모든 빈 조회
◦
`ac.getBean()` : 빈 이름으로 빈 객체(인스턴스)를 조회
•
애플리케이션 빈 출력하기
◦
스프링 내부에서 사용하는 빈은 제외하고, 내가 등록한 빈만 출력 할 수 있다.
◦
스프링이 내부에서 사용하는 빈은 `getRole()` 로 구분할 수 있다.
▪
`ROLE_APPLICATION` : 일반적으로 사용자가 정의한 빈
▪
`ROLE_INFRASTRUCTURE` : 스프링 내부에서 사용하는 빈