Backend/Spring

[Spring] @Component vs @Bean

누구세연 2024. 11. 16. 21:05

스프링 프레임워크에서 애플리케이션의 구성 요소를 관리할 때, `@Compnent`와 `@Bean`은 빈(Bean)을 등록하는 주요 방법입니다.

두 어노테이션은 비슷해 보이지만 실제 사용 목적과 방법은 다릅니다.

 

이번 글을 통해서 적재적소에 맞게 스프링 빈을 등록하는 방법을 알아보겠습니다.✍️

 

@Component란?

@Component

`@Component`는 개발자가 정의한 클래스(주로 도메인 계층 또는 애플리케이션의 주요 기능을 담당하는 클래스)를 스프링 컨테이너로 등록하기 위해 사용됩니다.

  1. 자동 스캔
    - `@Component`는 클래스패스 스캔(ComponentScan)을 통해 스프링이 자동으로 탐지하고 빈으로 등록합니다.
    - 별도의 설정 없이 클래스에 어노테이션만 추가하면 빈으로 관리됩니다.
  2. 어노테이션 타깃
    - 클래스, 인터페이스, 열거형(Enum)에 사용할 수 있습니다. (@Target(ElementType.TYPE))
  3. 레이어 역할 분류
    - `@Component`는 추상적인 개념으로 구체적인 역할을 명시하는 다른 어노테이션(예: @Controller, @Service, @Repository)의 기본 어노테이션 역할을 합니다.

사용 사례

  • 개발자가 작성한 클래스
    • 비즈니스 로직, 데이터 접근, 유틸리티 클래스 등을 빈으로 등록합니다.
  • 스프링의 자동 스캔 메커니즘 활용
    • 클래스가 프로젝트 패키지 내에 위치하면 @ComponentScan으로 간편하게 관리할 수 있습니다.

주의할 점

  • 스캔 범위 제한
    • `@SpringBootApplication`의 기본 스캔 범위는 애플리케이션 클래스와 그 하위 패키지입니다.
    • 스캔 범위를 벗어난 클래스는 빈으로 등록되지 않으므로, 필요한 경우 `@ComponentScan`에 직접 등록해야 합니다.

 

@Bean이란?

@Bean

`@Bean`은 개발자가 외부 라이브러리 또는 스프링이 자동으로 관리할 수 없는 객체를 수동으로 등록할 때 사용됩니다.

  1. 수동 등록
    - `@Bean`은 개발자가 직접 정의한 메서드를 통해 빈을 생성하고 스프링 컨테이너에 등록합니다.
    - 빈 생성을 제어해야 하거나 외부 라이브러리를 등록할 때 사용합니다.
  2. 어노테이션 타깃
    - 메서드(Method)와 어노테이션 유형(Annotation Type)에서 사용됩니다.
    (@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}))
  3. @Configuration과 함께 사용
    - 일반적으로 `@Configuration`클래스 내에서 정의되며 설정 파일의 일환으로 동작합니다.

사용 사례

  • 외부 라이브러리 객체 등록
    • 서드파티 라이브러리를 빈으로 등록해야 할 때 사용합니다.
  • 복잡한 빈 생성 로직
    • 객체 초기화, 소멸 메서드 호출, 특정 생성 방식을 요구하는 경우 사용됩니다.

 

주요 차이점 비교

특징 @Component @Bean
사용 대상 개발자가 작성한 클래스 외부 라이브러리 또는 수동으로 등록할 필요가 있는 객체
등록 방식 자동 스캔(ComponentScan)을 통해 스프링이 탐지 개발자가 메서드로 명시적으로 등록
타깃 클래스, 인터페이스, 열거형(Enum) 메서드
라이프 사이클 제어 스프링이 자동으로 관리 개발자가 빈 생성 로직을 세밀하게 제어 가능
사용 사례 서비스, 레포지토리, 컨트롤러 등 ObjectMapper, RestTemplate 등

 

 

언제 @Component와 @Bean을 사용할까?

@Component를 사용할 때

  • 클래스가 애플리케이션의 주요 구성 요소이며, 명확한 역할이 있는 경우
  • 빈 등록을 스프링의 자동 스캔 메커니즘에 맡기고 싶은 경우
  • 비즈니스 로직, 데이터 접근, 유틸리티 클래스를 구성하는 경우

@Bean을 사용할 때

  • 외부 라이브러리 객체를 등록하거나 특정 생성 방식(빌더, 팩토리 메서드 등)을 통해 빈을 생성해야 할 경우
  • 커스터마이징이 필요한 경우(ex: ObjectMapper, RestTemplate)
  • 생성 로직이 복잡하거나 동적으로 빈을 생성해야 하는 경우

 

@Component와 @Bean을 함께 사용할 수 있을까?

@Component와 @Bean은 상호 배타적이지 않습니다.

일반적으로, @Component는 애플리케이션 구성 요소로서의 역할을 맡고,@Bean은 외부 종속성을 주입하거나 수동으로 빈을 등록하는 데 사용됩니다.

 

예를 들어, @Component로 등록된 클래스가 @Bean메서드에서 의존성으로 사용될 수도 있습니다.

@Component
public class UserService {
    public String getUserInfo() {
        return "User Info";
    }
}

@Configuration
public class AppConfig {
    private final UserService userService;

    public AppConfig(UserService userService) {
        this.userService = userService;
    }

    @Bean
    public String userGreeting() {
        return "Hello!_! " + userService.getUserInfo();
    }
}

 

 

💡 두 어노테이션은 각자의 장단점과 목적이 뚜렷하므로 상황에 맞는 선택이 중요합니다.
자동화된 빈 등록: @Component는 스프링의 컴포넌트 스캔을 활용하여 클래스 기반으로 빈을 자동 등록할 때 적합합니다.
수동으로 세밀하게 등록: @Bean은 외부 라이브러리나 복잡한 생성 과정을 요구하는 객체를 등록할 때 유용합니다.
적절한 상황에서 두 가지를 조합하여 스프링 빈 관리를 효율적으로 설계하세요! 😊