> For the complete documentation index, see [llms.txt](https://yihyuns-gitbook.gitbook.io/today-i-learned/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yihyuns-gitbook.gitbook.io/today-i-learned/spring/spring_bean_life_cycle.md).

# Spring Bean의 생명주기(life-cycle)

## 빈의 생명주기

기본적으로 빈 스코프가 싱글톤으로 생성되면 스프링 컨테이너의 생성 시점에 빈도 생성되고 스프링 컨테이너의 소멸 시점에 빈도 소멸된다.

따라서 해당 글에서의 빈의 생명주기는 빈 스코프를 싱글톤으로 설정했을 때라고 가정한다.

빈 스코프는 [해당 게시물](/today-i-learned/spring/bean_scope.md) 참조

## 스프링 컨테이너의 생명주기

스프링 컨테이너는 아래와 같이 초기화와 종료라는 생명주기를 갖는다.

```java
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) {

				// 1. 컨테이너 초기화 (생성)
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(AppContext.class);

				// 2. 컨테이너 내에 등록된 빈 사용
        MyClass mc = context.getBean("myClass", MyClass.class);
        mc.print();

				// 3. 컨테이너 종료
        context.close();
    }

}
```

1. 컨테이너 초기화

   스프링 컨테이너가 생성된다. 스프링 컨테이너는 생성자의 인자로 전달되는 설정 클래스(@Configuration이 적용된 클래스)에서 정보를 읽어와 빈을 생성하고 연결(의존성 주입)한다.
2. 컨테이너 사용

   컨테이너가 초기화되고 나면 getBean을 통해 등록된 빈을 이용할 수 있다.
3. 컨테이너 종료

   컨테이너의 사용이 끝나면 컨테이너를 종료한다. 이 때 빈 객체도 모두 소멸한다.

## 스프링 빈의 생명주기

스프링 빈의 생명주기는 스프링 컨테이너의 생명주기에 의해 관리된다.

스프링 빈의 생명주기는 다음의 4단계로 나눌 수 있다.

1. 객체 생성 — 스프링 컨테이너 생성과 함께 생성
2. 의존 설정 — 스프링 컨테이너의 생성과 함께 설정
3. 초기화 — 1,2번이 완료된 후 스프링 컨테이너가 빈 객체의 초기화를 위한 지정 메소드 호출
4. 소멸 — 스프링 컨테이너 종료 시 스프링 컨테이너가 빈 객체의 소멸을 위한 지정 메소드 호출

### 빈 객체의 초기화와 소멸

* 초기화

  InitializingBean 인터페이스를 구현한 뒤 afterPropertiesSet 메서드를 오버라이딩하면 된다.

  ```java
  public interface InitializingBean {
  	void afterPropertiesSet() throw Exception;
  }
  ```
* 소멸

  DisposableBean 인터페이스를 구현한 뒤 destroy 메서드를 오버라이딩하면 된다.

  ```java
  public interface DisposableBean {
  	void destroy() throw Exception;
  }
  ```
* 예시

  ```java
  package com.yihyun.introduction;

  import org.springframework.beans.factory.DisposableBean;
  import org.springframework.beans.factory.InitializingBean;
  import org.springframework.stereotype.Component;

  @Component
  public class MyClass implements InitializingBean, DisposableBean {

      private String name;

      public void print() {
          System.out.println("hello " + name);
      }

      public void setName(String name) {
          this.name = name;
      }

      @Override
      public void afterPropertiesSet() throws Exception {
          System.out.println("myClass Bean 초기화");
      }

      @Override
      public void destroy() throws Exception {
          System.out.println("myClass Bean 소멸");
      }
  }

  ```

### 외부 클래스를 빈으로 등록하는 경우의 초기화와 소멸

보통 빈 등록을 위해 빈의 원형이 되는 클래스에 @Component 어노테이션을 적용하지만, 외부에서 제공받아 소스 코드가 없는 클래스의 경우에는 @Configuration에서 직접 빈으로 등록한다.

이 경우에는 위처럼 인터페이스를 구현할 수 없으므로 다음과 같이 초기화와 소멸 메소드를 지정하면 된다.

```java
@Bean(initMethod = "메소드명", destroyMethod = "메소드명")
public ExternalClass externalClass() {
	return new ExternelClass();
}
```
