Updated:

1. 개요

스프링은 스프링 컨테이너를 통해 객체를 관리하는데, 스프링 컨테이너에서 관리되는 객체를 빈(Bean)이라고 한다. 이번에는 스프링 컨테이너(Spring Container)에 대해 알아보도록 하자.

2. 스프링 컨테이너 종류

2.1 BeanFactory

객체를 생성하고, 객체 사이의 런타임 의존관계를 맺어주는 역할을 하는 스프링 컨테이너의 최상위 인터페이스

2.2 ApplicationContext

BeanFactory를 포함한 여러 인터페이스들을 상속받은 인터페이스로, 스프링 컨테이너라고 하면 일반적으로 ApplicationContext를 의미한다. BeanFactory와 마찬가지로 객체를 생성하고, 객체 사이의 런타임 의존관계를 맺어주는 역할 뿐만 아니라 메시지 다국화, 환경변수 등 다양한 기능을 추가로 제공한다.

  • ResourcePatternResolver : 리소스를 읽어오기 위한 인터페이스

  • EnvironmentCapable : 개발, 운영 등 환경을 분리해서 처리하고, 애플리케이션 구동 시 필요한 정보들을 관리하기 위한 인터페이스

  • MessageSource : 메시지 다국화를 위한 인터페이스

  • ApplicationEventPublisher : 이벤트 관련 기능들을 제공하는 인터페이스

3. 스프링 컨테이너 생성 과정

1) 스프링 컨테이너 생성

비어있는 스프링 컨테이너가 생성된다.

2) 스프링 빈 등록

스프링 설정 파일(Java, XML 등)을 기반으로 컨테이너에 스프링 빈이 등록된다.

3) 스프링 빈 의존관계 설정

스프링 설정 파일(Java, XML 등)을 기반으로 스프링 빈의 의존관계를 주입(DI)한다.

4. 스프링 컨테이너 생성

4-1. 자바 코드 이용

[AppConfig.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}

4-2. XML 이용

[appConfig.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="memberService" class="hello.core.member.MemberServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository" />
    </bean>

    <bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>

    <bean id="orderService" class="hello.core.order.OrderServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository" />
        <constructor-arg name="discountPolicy" ref="discountPolicy" />
    </bean>

    <bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy" />
</beans>

5. 스프링 빈 조회

5-1. 자바 설정파일

[소스 코드]

1
2
3
4
5
6
7
8
9
10
11
public class BeanTest {

    public static void main(String[] args) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println(beanDefinitionName + ", " + bean);
        }
    }
}

Line 4 : 자바 파일을 설정정보로 사용하기 위해 AnnotationConfigApplicationContext 이용

Line 5 : 모든 빈들의 이름을 가져와서 배열에 저장

Line 6 ~ 9 : 빈의 이름으로 빈을 가져와서 출력

[실행 결과]

5-2. XML 설정파일

[소스 코드]

1
2
3
4
5
6
7
8
9
10
11
public class BeanTest {

    public static void main(String[] args) {
        ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + ", object = " + bean);
        }
    }
}

Line 4 : XML을 설정정보로 사용하기 위해 GenericXmlApplicationContext 이용

Line 5 : 모든 빈들의 이름을 가져와서 배열에 저장

Line 6 ~ 9 : 빈의 이름으로 빈을 가져와서 출력

[실행 결과]

6. BeanDefinition

스프링은 BeanDefinition을 통해 다양한 형식의 설정파일을 지원한다. 어떠한 설정 파일을 사용하더라도 BeanDefinition 형식의 메타정보를 생성해주고, 스프링 컨테이너는 설정파일의 형식과 상관없이 BeanDefinition을 통해 빈의 정보를 알아낼 수 있다.

  • beanClassName : 생성할 빈의 클래스 이름

  • constructorArgumentValue : 생성자 이름과 설정값

  • dependsOn : 생성 순서가 보장되어야 하는 경우를 위해 먼저 생성되어야 하는 빈 지정

  • description : 빈 생성 시 작성한 설명

  • destroyMethodName : 빈의 생명주기가 끝나서 소멸되기전 호출되는 메서드 이름

  • factoryBeanName : 팩토리 역할의 빈을 사용할 경우 이름

  • factoryMethodName : 빈을 생성할 팩토리 메서드의 이름

  • initMethodName : 빈을 생성하고 의존관계 적용 후 호출되는 초기화 메서드 이름

  • parentName : 빈 메타정보를 상속받을 부모 BeanDefinition 이름

  • propertyValues : 빈의 새 인스턴스에 적용할 속성 값

  • resourceDescription : BeanDefinition이 나온 리소스에 대한 설명

  • scope : 빈 오브젝트의 생명 주기(default : 싱글톤)

Updated:

Leave a comment