Posts Bean 정리
Post
Cancel

Bean 정리

Bean

빈(Bean)이란 Spring의 IoC 컨테이너에서 의존성을 주입하기 위해 내부적으로 생성하는 객체를 말한다. 이렇게 컨테이너에서 의존성을 관리해주기 때문에 제어가 역전(IoC - Inversion of Control) 되었다고 하며 개발자가 직접 의존성 객체를 생성하고 주입해주지 않아도 되기 때문에 개발 과정이 간편해지는 장점이 있다.

빈을 등록하는 방식에는 @Component 어노테이션과 @Bean 어노테이션으로 등록하는 방법 두가지가 있다.

@Component클래스에서 사용가능하며 프레임워크에서 인스턴스를 생성한 후에 빈으로 등록 하도록 맡기는 방식이고,

@Bean메소드에서 사용가능하며 개발자가 생성할 인스턴스를 직접 설정하고 메소드의 return을 통해 내보낸 것을 프레임워크에서 관리하도록 맡기는 방식이다.

1) @Component 어노테이션으로 등록

1
2
3
4
@Component
public class MyComponent {
  ...
}

웹 어플리케이션을 구현하다 보면 흔히 사용하는 @Controller, @Service 어노테이션도 내부적으로 @Component 어노테이션이 포함되어 있기 때문에 빈으로 등록된다.

스크린샷 2021-01-11 오후 11 00 21

빈으로 등록할 컴포넌트를 찾는 조건의 설정은 @ComponentScan 어노테이션을 통해 설정할 수 있다.

스프링부트 프로젝트를 생성하면 메인 클래스에 @SpringBootApplication 어노테이션이 붙어있는 것을 볼 수 있는데, 해당 어노테이션 내부에 @ComponentScan 어노테이션이 포함되어 있다.

스크린샷 2021-01-11 오후 11 00 01

2) @Bean 어노테이션으로 등록

@Bean 어노테이션은 @Component와 달리 메소드에 붙인다. 그리고 이 메소드는 @Configuration 어노테이션이 붙어서 설정 파일 역할을 하는 클래스 내부에 등록되어야 한다.

1
2
3
4
5
6
7
@Configuration
public class MyConfiguration {
  @Bean
  public MyBean myBean() {
    return new MyBean();
  }
}

@SpringBootApplication 어노테이션에는 @Configuration 어노테이션 역시 내부적으로 포함되어 있기 때문에 메인 클래스에서도 빈 등록 설정을 할 수 있다.

스크린샷 2021-01-11 오후 11 03 41

Bean Scope

빈의 Scope 종류는 아래와 같으며, SingletonPrototype을 주로 사용한다고 한다. (둘 중에서도 대부분 Singleton 타입으로 사용한다고 한다.)

기본값은 Singleton 이다.

ScopeDescription
singleton(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocketScopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

Prototype Bean 생성

싱글톤 빈은 말 그대로 객체를 하나만 생성해놓고 재사용 하는 것을 말한다. 하나의 객체를 재사용하기 때문에 싱글톤의 단점을 그대로 가지고 있다. (멀티 스레드 환경에서 동시성 문제 같은)

프로토타입 빈은 싱글톤 빈과 달리 의존성을 주입할 때 새로운 객체를 생성하여 주입해주는 방식이다. 만약 개별 적으로 어떤 상태 값을 관리해야 한다면 싱글톤 빈보다 프로토타입 빈을 사용하는 것이 좋을 수 있다.

빈의 스코프를 재설정 하고 싶다면 @Scope 어노테이션을 사용하면 된다.

사용할 Scope를 스트링으로 입력해주어도 되지만 ConfigurableBeanFactory 인터페이스에 선언된 상수값을 사용할 수도 있다.(이 경우에는 singleton과 prototype 두 경우만 사용가능)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//@Component
@Component
@Scope("prototype") //또는 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyComponent {
  ...
}

//@Bean
@Configuration
public class MyConfiguration {
  @Bean
  @Scope("prototype")
  public MyBean myBean() {
    return new MyBean();
  }
}

주의할 점

싱글톤 빈에 프로토타입 빈을 주입하는 경우 프로토타입 빈의 동작에 문제가 발생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//SingletonBean
@Component
public class SingletonBean {

  private PrototypeBean prototypeBean;

  public SingletonBean(PrototypeBean prototypeBean) {
    this.prototypeBean = prototypeBean;
  }

  public String toStringPrototypeBean() {
    return prototypeBean.toString();
  }
}

//PrototypeBean
@Component
@Scope(scopeName = "prototype")
public class PrototypeBean {
  ...
}

//print
@Test
void proxyTest() {
  for (int i = 0; i< 3; i++) {
    System.out.println(ctx.getBean(SingletonBean.class).toStringPrototypeBean());
  }
}

스크린샷 2021-01-16 오후 8 07 50

이 경우에는 프로토타입 빈을 참조하더라도 같은 인스턴스를 참조하게 되는데, 프로토타입 빈의 Scope에 ProxyMode 를 설정하면 매번 새로운 인스턴스를 참조하도록 만들 수 있다.

1
2
3
4
5
6
@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PrototypeBean {
  ...
}

스크린샷 2021-01-16 오후 8 07 20

참고자료

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

NCP에서 HA 구성해보기

Atomic과 Synchronized

Comments powered by Disqus.