본문 바로가기
백엔드

[Spring] Bean Factory와 Application Context

by BeforB 2021. 9. 25.
728x90

 

 

IoC와 DI에 대해서 깊게 파보려니 역시 Bean과 BeanFactory, ApplicationContext에 대해 한 번쯤 깊게 알아봐야 할 것 같아서 정리해보려고 한다.

다른 사람들이 정리해놓은 글만 읽었을 때는 아무리 읽어도 이해가 안되더니, 역시 직접 코드를 보고 정리하니 내 것이 되는 기분이다.

 

 

Spring Container(스프링 컨테이너)란?

Bean Factory와 Application Context에 대해 이해하려면 우선 스프링 컨테이너에 대해 알아야 한다.

 

스프링 컨테이너란, 스프링 빈(Bean)의 생성과 소멸 등의 라이프사이클을 관리하고, 기능을 제공하며 IoC를 이용하여 애플리케이션 컴포넌트를 관리한다. 개발자가 작성한 코드의 처리과정을 위임받은 독립적인 존재라고 생각하면 된다. 일반적으로 '컨테이너' 혹은 'IoC 컨테이너'라고 부르기도 한다.

 

스프링 컨테이너에는 두 가지 종류가 있다. 바로 오늘의 주제인 Bean Factory와 Bean Factory를 상속한 Application Context이다.

 

 

 

 

1. org.springframework.beans.factory.BeanFactory

팩토리 디자인 패턴을 구현한 것으로, 빈을 생성하고 관리한다.

 

컨테이너가 구동될 때 Bean을 생성하느 것이 아니라 클라이언트의 요청에 의해서 Bean이 사용되는 시점에 생성하는 Lazy Loading 방식을 사용한다.

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

public interface BeanFactory {

	String FACTORY_BEAN_PREFIX = "&";

	Object getBean(String name) throws BeansException;

	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	Object getBean(String name, Object... args) throws BeansException;

	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

	boolean containsBean(String name);

	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	@Nullable
	Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
  
	String[] getAliases(String name);

}

 

 

 

2. org.springframework.context.ApplicationContext

ApplicationContext는 BeanFacotry를 상속하고 있으며 Bean의 생성과 관리를 담당한다. 정확히 말하자면 BeanFactory를 상속하며 Bean을 Listable하게 관리하는 ListableBeanFactory를 상속하고 있다.

 

package org.springframework.context;

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

 

ApplicationContext의 코드를 뜯어보면 getBean() 메소드가 있는데 이는 빈의 이름을 이용해서 빈을 찾아준다. 타입으로 검색하거나 특정 어노테이션이 설정된 빈을 찾을 수도 있다. Bean을 생성하고 관리하는 것 이외에도 EnvironmentCapable, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver도 함께 상속받아 스프링에서 제공하는 다양한 기능을 제공한다.

 

 

각각에 대해 간략하게 정리해 보았다.

 

1) EnvironmentCapable

Profile과 Property를 관리한다.

 

Profile이란, 특정 환경에서 실행할 빈들의 그룹이다. 예를 들어 프로젝트를 진행할 때 로컬, 개발, 운영 서버의 설정 환경들이 각각 다를 수 있는데 이를 나눠서 관리할 수 있도록 해주는 것이 바로 Profile이다. 각각의 환경에서 다른 빈을 사용하거나 특정 환경에서만 사용하는 빈을 등록하는 경우에 사용한다.

솔직히 나도 Profile 개념에 대해서는 입사하고 처음 알게되었다. 개인 프로젝트를 진행할 때는 로컬/운영의 설정이 크게 다르지 않아 Profile에 대해 접할 기회가 없었는데 입사해서 사내 프로젝트를 진행해보니 실제로 Profile을 통해서 로컬/개발/스테이지/운영 등의 설정을 따로 관리하고 있었다.

 

Property란, 애플리케이션 구동 시 필요한 정보들을 key-value 형태로 관리하며 각 Property에는 우선순위가 존재한다. application.properties 에 등록하는 것들을 생각하면 될 것 같다.

 

 

 

2) HierarchicalBeanFactory

코드를 확인해보면 BeanFacotry를 상속받고 있으며, 상위 빈팩토리를 반환하는 역할을 하는걸 확인할 수 있다.

public interface HierarchicalBeanFactory extends BeanFactory {
	// Return the parent bean factory, or {@code null} if there is none.
	@Nullable
	BeanFactory getParentBeanFactory();

	/**
	 * Return whether the local bean factory contains a bean of the given name,
	 * ignoring beans defined in ancestor contexts.
	 */
	boolean containsLocalBean(String name);
}

 

 

 

3) MessageSource

스프링은 다국어 처리를 위해 org.springframework.context.MessageSource 인터페이스를 제공한다. 예를 들어 서비스를 사용하는 지역별로 메시지를 해당 국가의 언어로 제공하고 싶을 때 사용할 수 있다.

실제로 사용하기 위해서는 아래 예시처럼 각 언어/국가 별로 .properties 파일을 생성하고 파일 내부에 메시지를 설정해주어야 한다.

파일명_ko_KR.properties
파일명_en_US.properties

 

 

 

4) ApplicationEventPublisher

스프링에서 이벤트 프로그래밍에서 필요한 인터페이스를 제공한다. 예를들어 Context가 생성되는 시점, 소멸되는 시점 등에 행할 이벤트들을 설정할 수 있다.

 

 

 

5) ResourcePatternResolver

ResourcePatternResolver는 ResourceLoader 인터페이스를 상속한다. ResourceLoader는 classPath에서 리소스를 읽어오거나, 상대경로/절대경로로 읽어오거나, URL로 읽어오거나 등 말그대로 리소스를 읽어오는 인터페이스이다.

 

 

 

 

 

 

 

728x90

댓글