거누의 개발노트

[Spring] 스프링 컨테이너와 빈 본문

Spring

[Spring] 스프링 컨테이너와 빈

Gogozzi 2022. 6. 9. 12:06
반응형

스프링 컨테이너와 빈

스프링 컨테이너는 자바 객체의 생명 주기를 관리하며, 생성된 자바 객체들에게 추가적인 기능을 제공하는 역할을 한다.

여기서 말하는 자바 객체를 스프링에서는 빈(Bean)이라고 부른다.

저번에 공부했던 IoC와 DI의 원리가 이 스프링 컨테이너에 적용된다.

개발자는 new 연산자, 인터페이스 호출, 팩토리 호출 방식으로 객체를 생성하고 소멸시킬 수 있는데, 스프링 컨테이너가 이 역할을 대신해 준다.

스프링 컨테이너의 종류

BeanFactory

BeanFactory는 빈을 등록하고 생성하고 조회하고 돌려주는 등 빈을 관리하는 역할을 한다.

빈을 추가할 때는 이런식으로 추가합니다.

@Configuration
public class AppConfig {

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

    @Bean
    public FixDiscountPolicy discountPolicy() {
        return new FixDiscountPolicy();
    }
}

스프링 컨테이너 안에 스프링 빈 저장소가 있고 위 그림처럼 빈이 저장된다고 생각하면 이해가 쉽다.

이제 컨테이너 안에 들어가 있는 빈을 사용해보자

public class Main {

    public static void main(String[] args) {
        final BeanFactory beanFactory = new AnnotationConfigApplicationContext(AppConfig.class);
        final OrderService orderService = beanFactory.getBean("orderService", OrderService.class);
        final Order order = orderService.createOrder(15, "샤프", 3000);
        System.out.println(order.getDiscountPrice());
    }
}

BeanFactory를 AnnotationConfigApplicationContext로 구현하고, AppConfig를 구성정보로 지정한다.

그리고 빈 저장소에서 orderService를 가져올건데 OrderService 타입을 지정해주지 않으면 Object 타입으로 오니 주의해야한다고 한다.

.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4e718207
13:52:20.460 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
13:52:20.738 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
13:52:20.741 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
13:52:20.743 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
13:52:20.745 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
13:52:20.758 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'appConfig'
13:52:20.767 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService'
13:52:20.793 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'discountPolicy'
1000

위 코드를 실행하면 이런 로그가 발생한다.

뭔가 긴 빈 이름은 미리 정의된 초기 빈들이고 appConfig, orderService, discountPolicy가 우리가 등록한 빈이라는 사실을 알 수 있다. 또한, OrderService는 DiscountPolicy를 주입해 주어야 하는데 스프링 컨테이너가 알아서 주입을 해 줍니다.

ApplicationContext

ApplicationContext도 BeanFactory처럼 빈을 관리할 수 있습니다. Main 코드에서 BeanFactory를 ApplicationContext로만 바꾸고 실행해 보면,

public class Main {

    public static void main(String[] args) {
        final ApplicationContext beanFactory = new AnnotationConfigApplicationContext(AppConfig.class);
        final OrderService orderService = beanFactory.getBean("orderService", OrderService.class);
        final Order order = orderService.createOrder(15, "샤프", 3000);
        System.out.println(order.getDiscountPrice());
    }
}

동일한 결과를 얻을 수 있다.

13:56:08.105 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@4e718207
13:56:08.136 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
13:56:08.391 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
13:56:08.396 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
13:56:08.398 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
13:56:08.401 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
13:56:08.417 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'appConfig'
13:56:08.431 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService'
13:56:08.458 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'discountPolicy'
1000

 

이 이유는 ApplicationContextBeanFactory의 상속을 받았기 때문이다.

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

	...
}

완전 정확히 BeanFactory 자체에 상속을 받은 것은 아니지만 빈을 관리하는 기능을 물려받은 것이다.

그리고 ApplicationContext는 그 외에도 국제화가 지원되는 텍스트 메시지 관리, 이미지같은 파일 자원을 로드, 리너스로 등록된 빈에게 이벤트 발생 알림 등 부가적인 기능을 가지고 있다.

그래서 스프링 컨테이너하면 주로 이 ApplicationContext를 뜻한다고 한다.

또한, 빈 관리라는 기능도 두 컨테이너가 동일한 기능을 하지는 않는다.

BeanFactory는 처음으로 getBean() 메소드가 호출된 시점에서야 해당 빈을 생성하고,
ApplicationContext는 Context 초기화 시점에 모든 싱글톤 빈을 미리 로드한 후 애플리케이션 가동 후에는 빈을 지연 없이 받을 수 있다.

 

22-06-09 싱글톤 컨테이너에 대해 정리하기

반응형
Comments