본문 바로가기
  • RATEL.SHO
[Spring]

Spring [day 2]

by ratelsho 2023. 5. 28.

1 . 4  제어의 역전(IoC)

오브젝트 팩토리

 

팩토리  - 객체의 생성 방법을 결정하고 그렇게 만들어진 오브젝트를 돌려주는 것, 이런 일을 하는 오브젝트를 팩토리(factory)라고 부른다.

 

설계도로서의 팩토리

애플리케이션을 구성하는 컴포넌트의 구조와 관계를 정의한 설계도 같은 역활을 한다고 볼 수 있다. 

 

오브젝트 팩토리의 활용

중복 문제를 해결하려면 분리해내는 게 가장 좋은 방법이다. 

 

제어권의 이전을 통한 제어관계 역전

제어의 역전 - 프로그램 제어 흐름 구조가 뒤바뀌는 것, 일반적으로 프로그램의 흐름은 main() 메소드와 같이 프로그램이 시작되는 지점에서 다음에 사용할 오브젝트를 결정하고, 결정한 오브젝트를 생성하고, 만들어진 오브젝트에 있는 메소드를 호출하고, 그 오브젝트 메소드 안에서 다음에 사용할 것을 결정하고 호출하는 식의 작업이 반복된다.  제어의 역전이란 이런 제어 흐름의 개념을 거꾸로 뒤집는 것이다. 제어의 역전에서는 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하지 않는다. 당연히 생성하지도 않는다. 또 자신도 어떻게 만들어지고 어디서 사용되는지 알 수 없다. 모든 제어 권한을 자신이 아닌 다른 대상에게 위임하기 때문이다. 제어의 역전에서는 제어권을 상위 템플릿 메소드에 넘기고 자신은 필요할 때 호출되어 사용되도록 한다. 자연스럽게 관심을 분리하고 책임을 나누고 유연하게 확장 가능한 구조로 만들기 위해 시행하는 과정이 바로 IoC를 적용하는 작업이다. 제어의 역전에서는 프레임워크 또는 컨테이너와 같이 애플리케이션 컴포넌트의 생성과 관계설정, 사용, 생명주기 관리 등을 관장하는 존재가 필요하다. 

 

라이브러리와 프레임워크의 차이

라이브러리를 사용하는 애플리케이션 코드는 애플리케이션 흐름을 직접 제어한다. 단지 동작하는 중에 필요한 기능이 있을 때 능동적으로 라이브러리를 사용할 뿐이다. 반면에 프레임워크는 거꾸로 애플리케이션 코드가 프레임워크에 의해 사용된다. 보통 프레임워크 위에 개발한 클래스를 등록해두고, 흐름을 주도하는 중에 개발자가 만든 애플리케이션 코드를 사용하도록 만드는 방식이다. 

 

- 최근에 툴킷, 엔진, 라이브러리 등도 유행을 따라서 무작정 프레임워크라도 부르기도 하는데 이는 잘못된 것이다. 프레임워크에는 분명한 제어의 역전 개념이 적용되어 있어야 한다. 애플리케이션 코드는 프레임워크가 짜놓은 틀에서 수동적으로 동작해야 한다.

 

1. 5  스프링의 IoC

스프링의 핵심을 담당하는 건, 바로 빈 팩토리 또는 애플리케이션 컨텍스트라고 불리는 것이다. 

 

1.5.1 오브젝트 팩토리를 이용한 스프링 IoC

 

애플리케이션 컨텍스트와 설정정보

- 스프링에서는 스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트를 빈(bean)이라고 부른다. 자바빈 또는 엔터프라이즈 자바빈(EJB)에서 말하는 빈과 비슷한 오브젝트 단위의 애플리케이션 컴포넌트를 말한다. 동시에 스프링 빈은 스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트를 가리키는 말이다.

 

- 스프링에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트를 빈 팩토리(bean factory)라고 부른다. 보통 빈 팩토리 보다는 이를 좀 더 확장한 애플리케이션 컨텍스트(application context)를 주로 사용한다. 애플리케이션 컨텍스트는 IoC 방식을 따라 만들어진 일종의 빈 팩토리라고 생각하면 된다. 빈 팩토리와 애플리케이션 컨텍스트라는 용어는 동일하다고 생각하면 된다. 빈팩토리라고 말할 때는 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점을 맞춘 것이고, 애플리케이션 컨텍스트라고 말할 때는 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 IoC 엔진이라는 의미가 좀더 부각된다고 보면된다. 

 

- 애플리케이션 컨텍스트를 별도의 정보를 참고해서 빈(오브젝트)의 생성, 관계설정 등의 제어 작업을 총괄한다. 애플리케이션 컨텍스트는 별도로 설정정보를 담고 있는 무엇인가를 가져와 이를 활용하는 범용적인 IoC엔진 같은 것이라고 볼 수 있다.

 

-바로 이 설계도라는 게 바로 이런 애플리케이션 컨텍스트와 그 설정정보를 말한다고 보면 된다. 그 자체로는 애플리케이션 로직을 담당하지는 않지만 loC  방식을 이용해 애플리케이션 컴포넌트를 생성하고, 사용할 관계를 맺어주는 등의 책임을 담당하는 것이다. 마치 건물이 설계도면을 따라서 만들어지듯이, 애플리케이션도 애플리케이션 컨텍스트와 그 설정정보를 따라서 만들어지고 구성된다고 생각할 수 있다. 

 

- 스프링의 빈 팩토리를 위한 오브젝트 설정을 담당하는 클래스라고 인식할 수 있도록 @Configuration이라는 애노테이션을 추가한다. 오브젝트를 만들어주는 메소드에는 @Bean이라는 애노테이션을 붙여준다. 

 

@Configuration -> 애플리케이션 컨텍스트 또는 빈 팩토리가 사용할 설정정보라는 표시

@Bean -> 오브젝트 생성을 담당하는 IoC용 메소드라는 표시

 

- getBean()은 기본적으로 Object 타입으로 리턴하게 되어 있어서 매번 리턴되는 오브젝트에 다시 캐스팅을 해줘야 하는 부담이있다. 자바 5 이상의 제네릭(generic) 메소드 방식을 사용해 getBean()의 두 번째 파라미터에 리턴 타입을 주면, 지저분한 캐스팅 코드를 사용하지 지 않아도 된다. 

 

1.5.2 애플리케이션 컨텍스트의 동작방식

오브젝트 팩토리에 대응되는 것이 스프링의 애플리케이션 컨텍스트다. 스프링에서는 이 애플리케이션 컨텍스트를 IoC 컨테이너라 하기도 하고, 간단히 스프링 컨테이너라고 부르기도 한다. 또는 빈 팩토리라고 부를 수도 있다. 애플리케이션 컨텍스트가 스프링의 가장 대표적인 오브젝트이므로, 애플리케이션 컨텍스트를 그냥 스프링이라고 부르는 개발자도 있다. 

 

 애플리케이션 컨텍스트를 사용하는 이유는 범용적이고 유연한 방법으로 IoC 기능을 확장하기 위해서다.

 

클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다.

- 애플리케이션 컨텍스트를 사용하면 오브젝트가  팩토리가 아무리 많아져도 이를 알아야 하거나 직접 사용할 필요가 없다. 일관된 방식으로 원하는 오브젝트를 가져올 수 있다.

 

애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.

- 애플리케이션 컨텍스트의 역할은 단지 오브젝트 생성과 다른 오브젝트와의 관계 설정만이 전부가 아니다. 오브젝트가 만들어지는 방식, 시점과 전략을 다르게 가져갈 수도 있고, 이에 부가적으로 자동생성. 오브젝트에 대한 후처리, 정보의 조합, 설정 방식의 다변화, 인터셉팅 등 오브젝트를 효과적으로 활용할 수 있는 다양한 기능을 제공한다. 또, 빈이 사용할 수 있는 기반기술 서비스나 외부 시스템과의 연동 등을 컨테이너 차원에서 제공해주기도 한다.

 

애플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공한다.

-애플리케이션 컨텍스트의 getBean() 메소드는 빈의 이름을 이용해 빈을 찾아준다. 타입만으로 빈을 검색하거나 특별한 애노테이션 설정이 되어 있는 빈을 찾을 수도 있다.

 

스프링 IoC의 용어 정리

 

빈 bean

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

 

빈 팩토리 bean factory

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

 

애플리케이션 컨텍스트 application context

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

 

설정정보/설정 메타정보 configuration metadata 

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

 

컨테이너 container 또는 IoC 컨테이너

loC 방식으로 빈을 관리한다는 의미에서 애플리케이션 컨텍스트나 빈 팩토리를 컨테이너 또는 IoC 컨테이너라고도 한다. 후자는 주로 빈 팩토리의 관점에서 이야기하는 것이고, 그냥 컨테이너 또는 스프링 컨테이너라고 할 때는 애플리케이션 컨텍스트를 가리키는 것이라고 보면 된다. 컨테이너라는 말 자체가 IOC의 개념을 담고 있기 때문에 이름이 긴 애플리케이션 컨텍스트 대신에 스프링 컨테이너라고 부르는 걸 선호하는 사람들도 있다. 또 컨테이너라는 말은 애플리케이션 컨텍스트보다 추상적인 표현이기도 하다. 애플리케이션 컨텍스트는 그 자체로Applicationcontext 인터페이스를 구현한 오브젝트를 가리키기도 하는데, 애플리케이션 컨텍스트 오브젝트는 하나의 애플리케이션에서 보통 여러 개가 만들어져 사용된다. 이를 통틀어서 스프링 컨테이너라고 부를 수 있다. 때로는 컨테이너라는 말을 떼고 스프링이라고 부를 때도, 바로 이 스프링 컨테이너를 가리키는 것일 수 있다. 예를 들어 '스프링에 빈을 등록하고'라는 식으로 말하는 경우에 스프링이라는 말은 스프링 컨테이너 또는 애플리케이션 컨텍스트를 가리키는 말이다.

 

스프링 프레임워크

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