[Spring Core Technologies] 1.3

yoon·2022년 1월 31일
0

1.3. Bean Overview

Spring IoC container는 빈들을 관리하며, 이 빈들은 configuration metadata를 통해 생성된다.
BeanDefinition object를 통해 bean definition들은 표현되고, 이들은 아래와 같은 metadata를 가진다.

  • pacakage-qualified class name: 빈이 정의된 실제 구현 클래스
  • bean behavioral configuration elemenets: scope, lifecycle callback과 같은 빈이 container에서 어떻게 행동해야하는지 알려준다
  • references to other beans: 빈이 일하기 위해 필요한 다른 빈들에 대한 references. collaborators 혹은 dependencies라고도 부른다
  • other configuration settings to set in the newly created object: pool의 size limit, connections 수와 같은 정보.

이러한 metadata는 bean definition을 위한 property로 translate된다.

ApplicationContext는 user에 의해 container 바깥에서 생성된 BeanDefinition object를 등록할 수 있게 해준다. getBeanFactory() 메소드를 통해 ApplicationContext의 BeanFactory에 접근할 수 있고, return 값인 DefaultListableBeanFactory는 registerSingleton(), registerBeanDefinition() 메소드를 제공하여 이를 가능하게 한다. 하지만, 평범한 bean definition metadata를 이용하여 빈들을 생성하는것이 일반적이다.

1.3.1. Naming Beans

모든 빈들은 하나 혹은 여러개의 컨테이너 안에서 unique한 identifier를 가진다. 빈들은 보통 하나의 식별자를 가지며, 여러개의 가질 경우 다른 식별자들은 alias로 생각된다.

XML-based configuration metadata에서는, id 혹은 name attrirbute를 빈 식별자를 특정하기 위해서 사용한다. id attribute는 오직 하나의 식별자를 특정할 수 있게 하며, 다른 별명들을 위해서는 name attribute를 사용할 수 있다. 식별자는 관습적으로 camel-cased의 영숫자(e.g. myBean)로 이루어져 있지만, 특수 문자를 포함할 수도 있다.

빈에 대한 식별자를 꼭 지정할 필요는 없다. 특별히 식별자를 지정하지 않는다면, 컨테이너가 classpath를 component scanning할 때 식별자를 생성해준다. 보통의 경우 관습을 따라 naming이 이루어지지만, 카멜 케이스를 따르지 않는 경우에는 original casing을 그대로 유지한다. ref element를 사용해서 빈을 식별자를 통해 참조하고 싶다면, 이름을 지정해주어야 한다.

bean naming convention에 따라 네이밍하는것은 configuration을 읽고 이해하기 쉽게 할 뿐 아니라, 스프링 AOP를 사용할 때 유용하다.

Aliasing a Bean outside the Bean Definition

id attribute와 여러개의 name attribute를 조합하면, 빈을 하나 이상의 이름으로 칭할 수 있다. 이는 application 안의 각각의 component가 참조하는 일반적인 빈을 컴포넌트마다 각각 다른 이름으로 칭하는 등의 상황에서 유용하다.

하지만, 빈이 정의되는 곳에서 모든 aliases를 특정하는 것이 항상 적절한 것은 아니다. 때로는 다른 곳에서 소개된 빈에 대한 alias를 정의하는 것이 바람직하다. configuration이 각각의 subsystem별로 분리되어 있고, 각각의 subsystem에 그들만의 객체를 갖고 있는 큰 시스템이 그러한 경우다. XML-based configuration metadata에서는, < alias /> element를 사용하면 alias를 지정할 수 있다.

< alias name="myApp-dataSource" alias="subsystemA-dataSource" />
< alias name="myApp-dataSource" alias="subsystemB-dataSource" />

위와 같은 configuration을 통해, 각각의 컴포넌트와 메인 어플리케이션이 같은 빈을 사용하면서도 다른 이름으로 부를 수 있다.

Java-configuration을 사용한다면, @Bean 어노테이션을 사용하여 aliases를 제공할 수 있다.

1.3.2. Instantiating Beans

bean definition은 하나 이상의 객체를 생성하기 위한 레시피이다. 컨테이너는 bean definition을 이용하여 실제 객체를 생성한다.

XML-based configuration metadata를 사용한다면, < bean /> element의 class attribute를 사용하여 인스턴스화되는 객체의 타입을 특정한다. 이 class attribute(내부적으로는 BeanDefinition instance의 Class property)는 보통 필수적이다. Class property는 아래 두 가지 방법 중 하나로 사용할 수 있다.

  • 일반적으로, container가 빈의 생성자를 통해 직접 생성 => 자바 코드와 같이 new operator를 사용
  • container가 빈을 생성하기 위해서 클래스의 static factory method를 invoke

nested class에서 bean definition을 구성하기 위해서는, nested class의 binary name 혹은 source name을 사용해야 한다. 예시로, com.example package 안의 SomeThing class 안의 static nested class인 OtherThing이 존재한다고 하자. 이 때 OtherThing의 bean definition의 class attribute는

  • com.example.SomeThing$OtherThing
  • com.example.SomeThign.OtherThing

와 같은 형태이다.

Instantiation with a Constructor

생성자를 통하여 빈을 생성할 때에는, 특별한 코드나 구현 없이 그저 빈 클래스를 정의하는 것으로 충분하다. 하지만, IoC의 타입에 따라 default empty constructor가 필요할 수 있다.

스프링 IoC container는 JavaBeans에 국한되지 않고 모든 클래스를 관리할 수 있다. 대부분의 스프링 사용자들은 default (no-argument) constructor와 적절한 게터와 세터를 가진 JavaBeans을 선호한다. 스프링은 JavaBean specification을 따르지 않는 non-bean-style 클래스 또한 관리할 수 있다.

Instantiation with a Static Factory Method

static factory method로 빈을 생성할 때에는, static factory method를 포함하고 있는 class를 특정하기 위한 class attribute와 static factory method를 특정하기 위한 factory-method attribute를 사용해야한다.

< bean id="clientService"
    class="examples.ClientService"
    factory-method="createInstance" />

Instantiation by Using an Instance Factory Method

static factory method와 유사하게, 새로운 빈을 생성하기 위해서 이미 존재하는 빈의 non-static method를 invoke하여 빈을 생성한다. 이 경우, class attribute는 정의하지 않으며 factory-bean attribute에 method가 존재하는 빈의 이름을, 그리고 factory-method attribute에 메소드 자신을 정의해야 한다.

< bean id="clientService"
    factory-bean="serviceLocator"
    factory-method="createClientServiceInstance" />

하나의 factory class는 하나 이상의 factory method를 가질 수 있다.

Determining a Bean's Runtime Type

빈의 runtime type을 결정하는 것은 중요하지 않다. bean metadata definition에 있는 class는 그저 최초 클래스일 뿐이며, FactoryBean과 결합되며 다른 runtime type의 빈이 되거나, instance-level factory method의 경우 설정되지 않을 수도 있다. 추가적으로, AOP 프록시는 빈의 실제 타입의 노출을 제한하고 interface-based proxy로 감쌀 수도 있다.

빈의 runtime type을 알기 위해 추천하는 방법은 BeanFactory.getType 을 사용하는 것이다.

0개의 댓글