Spring

Spring Boot Run: 내부 동작 과정과 Bean 등록

curiousKidd 2024. 12. 23. 23:06
반응형

Spring Boot 애플리케이션을 실행할 때, 여러 단계의 과정을 거쳐 애플리케이션이 구동됩니다. 이 글에서는 Spring Boot의 실행 과정, Bean 등록 과정, 그리고 IOC(Inversion of Control)와 DI(Dependency Injection)가 이 과정에 어떻게 녹아있는지 정리합니다.


1. Spring Boot Application 시작

Spring Boot 애플리케이션은 @SpringBootApplication 어노테이션으로 시작합니다. 이 어노테이션은 세 가지 어노테이션을 포함합니다:

  • @SpringBootConfiguration: @Configuration을 포함하며, Spring 컨텍스트를 위한 설정 클래스를 나타냅니다.
  • @EnableAutoConfiguration: 클래스패스와 종속성을 기반으로 Spring Boot의 자동 설정을 활성화합니다.
  • @ComponentScan: 현재 패키지와 하위 패키지에서 @Component, @Service, @Repository, @Controller 등으로 지정된 클래스를 스캔합니다.

Spring Boot의 실행은 SpringApplication.run() 메서드를 호출하면서 시작됩니다.


2. 실행 단계: 주요 프로세스

  1. SpringApplication 객체 생성

    • SpringApplication 객체가 생성되며, 애플리케이션의 설정 정보를 초기화합니다.
    • Web 애플리케이션 여부를 감지합니다.
  2. SpringApplicationRunListeners 실행

    • ApplicationContext가 생성되기 전에 실행됩니다.
    • 이 단계에서 환경(Environment) 정보가 초기화됩니다.
  3. Environment 준비

    • ApplicationContext에서 사용할 프로파일과 속성(Property)을 로드합니다.
    • application.properties 또는 application.yml 파일을 기반으로 환경 설정이 이루어집니다.
  4. ApplicationContext 생성

    • ApplicationContext는 Spring의 핵심 컨테이너로, Bean을 관리합니다.
    • Web 애플리케이션의 경우 AnnotationConfigServletWebServerApplicationContext가 생성됩니다.
  5. Bean 등록 및 초기화

    • @ComponentScan으로 스캔된 클래스와 @Configuration으로 정의된 Bean이 등록됩니다.
    • Bean의 라이프사이클은 다음과 같이 진행됩니다:
      1. 인스턴스화: 클래스의 객체가 생성됩니다.
      2. 의존성 주입: 생성자 주입, 세터 주입 등을 통해 의존성이 주입됩니다.
      3. 초기화: @PostConstruct 또는 InitializingBeanafterPropertiesSet() 메서드가 호출됩니다.
  6. ApplicationContext 초기화 완료

    • Bean 등록과 의존성 주입이 완료된 후, 컨텍스트가 초기화됩니다.
  7. CommandLineRunner 및 ApplicationRunner 실행

    • 애플리케이션 시작 후 초기화 작업을 실행합니다.

3. Bean 등록: IOC와 DI의 역할

Spring Framework의 핵심은 IOC(Inversion of Control)DI(Dependency Injection)입니다.

  • IOC (제어의 역전)

    • 객체의 생성 및 생명 주기를 개발자가 아닌 Spring 컨테이너가 관리합니다.
    • 개발자는 객체 간의 의존성을 명시적으로 정의할 필요 없이, Spring 컨테이너에 맡깁니다.
  • DI (의존성 주입)

    • 의존성 객체를 생성자, 세터, 또는 필드 주입을 통해 주입합니다.
    • Spring 컨테이너는 필요한 의존성을 찾아 Bean에 주입합니다.

Spring Boot에서 IOC와 DI가 적용되는 과정:

  1. @ComponentScan으로 애플리케이션 전역에서 스캔된 클래스가 Spring 컨테이너에 의해 관리됩니다.
  2. 등록된 Bean 간의 의존성을 확인하고, 필요한 의존성을 생성하여 주입합니다.
  3. Bean의 라이프사이클을 관리하며, 필요한 초기화 작업과 종료 작업을 수행합니다.

4. Spring과 JSR-330의 관계

JSR-330(Java Specification Request 330)은 Java 애플리케이션에서 의존성 주입을 표준화한 스펙입니다. JSR-330은 다양한 DI 프레임워크 간의 호환성을 높이고, 특정 프레임워크에 종속되지 않는 코드를 작성할 수 있도록 합니다. Spring Framework는 이 표준을 지원하며, javax.inject 패키지의 어노테이션을 사용할 수 있습니다.

JSR-330의 주요 어노테이션:

  • @Inject: Spring의 @Autowired와 유사하게 의존성을 주입합니다.
  • @Named: Spring의 @Qualifier와 유사하며, 특정 이름의 Bean을 지정합니다.
  • @Singleton: Singleton 범위를 정의하며, Spring의 기본 스코프와 동일합니다.
  • @Provider: Lazy Initialization(지연 초기화)을 지원합니다.

Spring에서 JSR-330 어노테이션 활용:

  1. Spring은 JSR-330 어노테이션을 자동으로 인식하고 처리합니다.
  2. 개발자는 Spring 전용 어노테이션(@Autowired, @Qualifier) 대신 JSR-330 어노테이션을 사용하여 코드의 이식성을 높일 수 있습니다.

Spring과 JSR-330의 차이점:

  • Spring 전용 어노테이션은 Spring Framework와 밀접하게 통합되어 있으며, 더 많은 기능을 제공합니다.
  • JSR-330 어노테이션은 범용적으로 사용할 수 있으며, 다른 DI 프레임워크에서도 동일하게 동작합니다.

비교 그림:

  • 아래 그림은 Spring과 JSR-330 어노테이션의 관계를 시각적으로 보여줍니다.

    Spring vs JSR-330

    (참고: 위 이미지는 개념적인 관계를 설명하기 위한 예시입니다.)


5. 주요 클래스 및 인터페이스

Spring Boot 애플리케이션 실행 과정에서 다음과 같은 주요 클래스와 인터페이스가 관여합니다:

  • SpringApplication: 애플리케이션 부트스트랩 역할을 합니다.
  • ApplicationContext: Spring 컨테이너를 대표하며, Bean을 관리합니다.
  • BeanFactory: Bean 생성 및 관리의 최상위 인터페이스입니다.
  • CommandLineRunner / ApplicationRunner: 애플리케이션 초기화 후 실행될 코드를 정의합니다.

반응형