Post

Spring Study Group Week3 - 스프링 빈과 스프링 컨테이너

스프링 스터디 3주차 공부한 것입니다.


Spring에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC(Inversion of Control) 컨테이너인 빈 팩토리(Bean Factory)가 존재한다. 하지만 실제로는 빈의 생성과 관계설정 외에 추가적인 기능이 필요한데, 이러한 이유로 Spring에서는 빈 팩토리를 상속받아 확장한 애플리케이션 컨텍스트(Application Context)를 주로 사용한다.

애플리케이션 컨텍스트는 별도의 설정 정보를 참고하고 IoC를 적용하여 빈의 생성, 관계설정 등의 제어 작업을 총괄한다. 애플리케이션 컨텍스트에는 직접 오브젝트를 생성하고 관계를 맺어주는 코드가 없고, 그런 생성 정보와 연관관계 정보에 대한 설정을 읽어 처리한다. 예를 들어 @Configuration과 같은 어노테이션이 대표적인 IoC의 설정정보이다.


Spring Bean

스프링에서는 스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트빈(bean)이라고 부른다. 자바빈 또는 엔터프라이즈 자바빈(EJB)에서 말하는 빈과 비슷한 오브젝트 단위의 어플리케이션 컴포넌트를 말한다.

스프링 빈은 스프링 컨테이너생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트를 가리키는 말이다.

1
2
3
4
자바빈: 비주얼 툴에서 조작 가능한 컴포넌트. 자바의 주력 플랫폼이 웹 기반의 엔터프라이즈 방식으로 바뀌면서 비주얼 컴포넌트로서 자바빈은 인기를 잃어갔지만, 자바빈의 몇 가지 코딩 관례는 JSP 빈, EJB와 같은 표준 기술과 자바빈 스타일의 오브젝트를 사용하는 오픈소스 기술을 통해 계속 이어져 왔다. 이제는 자바빈이라고 말하면 다음 두 가지 관례를 따라 만들어진 오브젝트를 가리킨다. 간단히 빈이라고 부르기도 한다.

 - 디폴트 생성자: 자바빈은 파라미터가 없는 디폴트 생성자를 가지고 있어야한다. 툴이나 프레임워크에서 리플렉션을 이용해 오브젝트를 생성하기 때문에 필요하다.
 - 프로퍼티: 자바빈이 노출하는 이름을 가진 속성을 프로퍼티라고 한다. 프로퍼티는 setter와 getter를 이용해 수정 또는 조회할 수 있다.


Bean Factory

빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트빈 팩토리라고 부른다.

보통 빈 팩토리보다는 이를 좀 더 확장한 Application Context를 주로 사용한다.


Application Context

IoC 방식을 따라 만들어진 일종의 빈 팩토리이다. 별도의 설정 정보를 참고하고 IoC를 적용하여 빈의 생성, 관계설정 등의 제어 작업을 총괄한다. 애플리케이션 컨텍스트에는 직접 오브젝트를 생성하고 관계를 맺어주는 코드가 없고, 그런 생성 정보와 연관관계 정보에 대한 설정을 읽어 처리한다. 예를 들어 @Configuration과 같은 어노테이션이 대표적인 IoC의 설정정보이다.

빈 팩토리는 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점을 맞춘 것이고, 애플리케이션 컨텍스트는 애플리케이션 전반에 걸쳐 모든 구성요소의 작업을 담당하는 IoC의 엔진이라는 의미가 좀 더 부각한 것이다.

스프링에서는 어플리케이션 컨텍스트를 IoC 컨테이너라고 부르기도 하고, 스프링 컨테이너라고 부르기도 한다. 또는 빈 팩토리라고 부를 수도 있다. 어플리케이션 컨텍스트는 ApplicationContext 인터페이스를 구현하는데, ApplicationContext는 빈 팩토리가 구현하는 BeanFactory 인터페이스를 상속했으므로 어플리케이션 컨텍스트는 일종의 빈 팩토리인 셈이다.

스프링의 가장 대표적인 오브젝트이므로 그냥 스프링이라고 부르는 개발자도 있다.


동작 방식

어플리케이션 컨텍스트는 어플리케이션에서 IoC를 적용해서 관리할 모든 오브젝트에 대한 생성과 관계설정을 담당한다. 어플리케이션 컨텍스트에 따로 직접 오브젝트를 생성하고 관리해주는 코드가 없고, 생성정보와 연관관계 정보를 별도의 설정정보를 통해 얻는다. 때로는 외부의 오브젝트 팩토리에 그 작업을 위임하고 그 결과를 가져다가 사용하기도 한다.

image

해당 그림을 보면 어플리케이션 컨텍스트의 동작 방식을 알 수 있다.

  1. 어플리케이션 컨텍스트는 DaoFactory 클래스를 설정정보로 등록해두고, @Bean 이 붙은 메소드의 이름을 가져와 빈 목록을 만들어 놓는다.
  2. 클라이언트가 어플리케이션 컨텍스트의 getBean() 메소드를 호출한다.
  3. 자신의 빈 목록에서 요청한 이름이 있는지 찾고, 있다면 빈을 생성하는 메소드를 호출해서 오브젝트를 생성시킨 후 클라이언트에 돌려준다.

애플리케이션 컨택스트는 @Configuration이 붙은 클래스들을 설정 정보로 등록해두고, @Bean이 붙은 메소드의 이름으로 빈 목록을 생성한다. 그리고 클라이언트가 해당 빈을 요청한다면 애플리케이션 컨텍스트는 자신의 빈 목록에서 요청한 이름이 있는지 찾고, 있다면 해당 빈 생성 메소드(@Bean)을 호출하여 객체를 생성하고 돌려준다. (구체적으로는 Spring 내부에서 Reflection API를 이용해 빈 정의에 나오는 클래스 이름을 이용하거나 또는 빈 팩토리를 통해 빈을 생성한다.)


장점

  • 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다. 어플리케이션이 발전하면 IoC를 적용한 오브젝트도 계속 추가될 것이다. 클라이언트가 필요한 오브젝트를 가져오려면 어떤 팩토리 클래스를 사용해야할지 알아야 하고, 필요할 때마다 팩토리 오브젝트를 생성해야하는 번거로움이 있다. 하지만 어플리케이션 컨텍스트를 사용하면 일관된 방식으로 원하는 오브젝트를 가져올 수 있다.
  • 어플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다. 어플리케이션 컨텍스트는 단지 오브젝트 생성과 관계설정만이 전부가 아니다. 오브젝트가 만들어지는 방식, 시점과 전략을 다르게 가져갈 수도 있고, 부가적으로 오브젝트를 효과적으로 활용할 수 있는 다양한 기능을 제공해준다. 그리고 빈이 사용할 수 있는 기반기술 서비스나 외부 시스템과의 연동 등을 컨테이너 차원에서 제공해주기도 한다.
  • 어플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공한다. 어플리케이션 컨텍스트의 getBean() 메소드는 빈의 이름을 이용해 빈을 찾아준다. 타입만으로 빈을 검색하거나 특별한 어노테이션 설정이 되어있는 빈을 찾을 수도 있다.


빈 스캐닝과 자동 와이어링

Autowired

@Autowired는 자동 와이어링 기법을 이용해서 조건에 맞는 빈을 찾아 자동으로 수정자 메소드나 필드에 넣어준다. 자동 와이어링을 사용하면 컨테이너가 이름이나 타입을 기준으로 주입될 빈을 찾아주기 때문에 빈의 프로퍼티 설정을 직접 해주는 자바 코드나 XML 양을 대폭 줄일 수 있다. 그러나 빈 설정정보를 보고 다른 빈과 의존관계가 어떻게 맺어져 있는지 힘들다는 단점이 있다.


Component

@Component는 스프링이 어노테이션에 담긴 메타 정보를 이용하기 시작했을 때 @Autowired와 함께 소개된 대표적인 어노테이션이다. @Component는 클래스에 부여되며 해당 어노테이션이 붙은 클래스는 빈 스캐너를 통해 자동으로 빈으로 등록된다. 정확히는 @Component 또는 @Component를 메타 어노테이션으로 갖고있는 어노테이션이 붙은 클래스가 자동 빈 등록 대상이다.


ComponentScan

@Component 어노테이션이 달린 클래스를 자동으로 찾아서 빈을 등록해주게 하려면 빈 스캔 기능을 사용하겠다는 어노테이션 정의가 필요하다. 빈 자동등록이 컨테이너가 디폴트로 제공하는 기능은 아니기 때문이다. 프로젝트 내의 모든 클래스패스를 다 뒤져서 @Component 어노테이션이 달린 클래스를 찾는 것은 부담이 많은 작업이다. 그래서 특정 패키지 아래에서만 찾도록 기준이 되는 패키지를 지정해줄 필요가 있다. 이때 사용되는 어노테이션이 @ComponentScan이다.

1
2
3
4
5
6
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages="springboot.user")
public class TestApplicaionContext {
	...
}

@ComponentScanbasePackages 엘리먼트는 @Component가 붙은 클래스를 스캔할 기준 패키지를 지정할 때 사용한다. 기준 패키지는 여러개 넣어도 되며 지정한 패키지 아래의 모든 서브 패키지를 다 검색하게 된다. @Component가 붙은 클래스가 발견되면 새로운 빈을 자동으로 추가한다. 빈의 클래스는 @Component가 붙은 클래스이고, 빈의 아이디는 따로 지정하지 않았으면 클래스 이름의 첫 글자를 소문자로 바꿔서 사용한다.


용어정리

Bean 빈

빈 또는 빈 오브젝트는 스프링이 IoC 방식으로 관리하는 오브젝트라는 뜻이다. 관리되는 오브젝트(managed object)라고 부르기도 한다. 스프링을 사용하는 어플리케이션에서 만들어지는 모든 오브젝트가 다 빈은 아니다. 그 중에서 스프링이 직접 그 생성과 제어를 담당하는 오브젝트만을 빈이라고 부른다.

Bean Factory 빈 팩토리

스프링의 IoC를 담당하는 핵심 컨테이너를 가리킨다. 빈을 등록, 생성, 조회, 돌려주고, 그 외에 부가적인 빈을 관리한다. 보통은 빈 팩토리를 바로 사용하지 않고 이를 확장한 어플리케이션 컨텍스트를 이용한다. BeanFactory 라고 붙여쓰면 빈 팩토리가 구현하고 있는 가장 기본적인 인터페이스의 이름이 된다. 이 인터페이스에 getBean()과 같은 메소드가 정의되어 해당 메소드를 통해 빈을 인스턴스화할 수 있다.

Application Context 어플리케이션 컨텍스트

빈 팩토리를 확장한 IoC 컨테이너이다. 빈 팩토리의 기능에 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다. 빈 팩토리라고 부를 때는 주로 빈의 생성과 제어의 관점에서 이야기하는 것이고, 어플리케이션 컨텍스트라고 할 때는 스프링이 제공하는 어플리케이션 지원 기능을 모두 포함해서 이야기하는 것이라고 보면 된다. 스프링에서는 빈 팩토리보다 어플리케이션 컨텍스트라는 용어를 더 많이 사용한다. ApplicationContext 인터페이스는 BeanFactory를 상속한다.

Configuration Metadata 설정정보 / 설정 메타정보

스프링의 설정정보란 어플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타 정보를 말한다. 영어로 Configuration 이라고 하는데, 이는 구성정보 내지는 형상정보라는 의미다. 실제로 스프링의 설정정보는 컨테이너에 어떤 기능을 세팅하거나 조정하는 경우보다 IoC 컨테이너의 컨테이너에 의해 관리되는 어플리케이션 오브젝트를 생성하고 구성할 때 사용된다. 어플리케이션의 형상정보라고 부르기도 한다.

Container or IoC Container 컨테이너 또는 IoC 컨테이너

IoC 방식으로 빈을 관리한다는 의미에서 어플리케이션 컨텍스트나 빈 팩토리를 컨테이너 또는 IoC 컨테이너라고도 한다. 후자는 주로 빈 팩토리의 관점에서 이야기하는 것이고 그냥 컨테이너 또는 스프링 컨테이너라고 할 때는 어플리케이션 컨텍스트를 가리키는 것이라고 보면 된다.

컨테이너라는 말 자체가 IoC의 개념을 담고있기 때문에 긴 어플리케이션 컨텍스트 대신에 스프링 컨테이너라고 부르는 것을 선호하는 사람도 있다.

또 컨테이너라는 말은 그 자체로 ApplicationContext 인터페이스를 구현한 오브젝트를 가리키기도 하는데, 어플리케이션 컨텍스트 오브젝트는 하나의 어플리케이션에서 보통 여러 개가 만들어져 사용된다. 이를 통틀어 스프링 컨테이너라고 부를 수 있다.

때로 컨테이너라는 말을 떼고 스프링이라고 부를 때도 스프링 컨테이너를 가리키는 것일 수도 있다. ‘스프링에 빈을 등록하고’식으로 말하는 경우가 그 예이다.

Spring Framework 스프링 프레임워크

IoC 컨테이너, 어플리케이션 컨텍스트를 포함해서 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용한다. 그냥 스프링이라고 줄여 말하기도 한다.

This post is licensed under CC BY 4.0 by the author.