본문 바로가기
  • 냥냥냥
Spring

Bean vs Component 차이점이 뭘까

by 프로그래밍데 2025. 3. 31.

Spring으로 개발을 하다보면

@Bean과 @Component의 차이점이 뭔지 의문을 가질 때가 많다.

 

@Bean && @Component 공통점 

애플레케이션 컨텍스트에 Bean을 등록할 때 사용하는 어노테이션이다.
(애플리케이션 컨텍스트 같은 경우에는 다음 게시글에서 자세히 쓸 예정이다.)

둘의 차이점은 사용 목적에 있어 나타난다. 

 

예를 들어, 실무에서는 주로

외부 라이브러리에서 제공하는 클래스들 : @Bean을 통해 등록하고,

애플리케이션의 특정 기능을 담당하는 사용자 정의 클래스들 : @Component를 사용해 등록하는 경우가 다수다.

 

@Bean과 @Component의 차이점

@Bean:

주로 개발자가 외부 라이브러리의 클래스를 빈으로 등록하고자 할 때 사용된다.

Bean : Method

예를 들어, ObjectMapper와 같은 외부 라이브러리 클래스를 빈으로 등록하려면 @Bean을 사용해야 한다.
@Bean은 메소드 수준에서 적용되며, 해당 메소드에서 반환된 객체가 빈으로 등록된다.
이 경우 객체의 생성이나 초기화 과정을 개발자가 직접 관리할 수 있다.

 

 

@Component:

이 어노테이션은 일반적으로 애플리케이션에서 직접 작성한 클래스를 빈으로 등록할 때 사용한다.

이때, 해당 클래스는 Spring이 관리하는 객체로 등록되며, 별도의 메소드가 필요 없다.

Component : Type

예를 들어, 서비스 계층의 @Service,
데이터베이스 접근을 담당하는 @Repository,
HTTP 요청을 처리하는 @Controller 등도 모두
내부적으로 @Component 어노테이션을 상속받는다.

 

Controller, Service, Repository 다 내부적으로 Component 어노테이션이 있다. 

@Service 비즈니스 로직을 처리하는 서비스 계층
@Repository DB 접근을 담당하는 DAO 클래스
@Controller HTTP 요청을 처리하는 웹 컨트롤러
@Component 특정한 계층에 속하지 않는 일반적인 빈 (유틸리티, 이벤트 핸들러, AOP 등)

👉 즉, @component 어노테이션은 기본적으로 특정한 계층에 속하지 않는 일반적인 Bean을 정의할 때 사용된다. 

 

 

결론 

@Bean의 경우 개발자가 컨트롤이 불가능한 

외부 라이브러리들을 Bean으로 등록하고 싶은 경우에 사용된다고 보면 된다. 

코드를 한 번 작성해보자면 

ObjectMapper의 경우 ObjectMapper Class에 @Component를 선언할수는 없으니 

ObjectMapper의 인스턴스를 생성하는 메소드를 만들고 해당 메소드에

@Bean을 선언하여 Bean으로 등록하여 사용 한다. 

 

 Component 어노테이션을 선언하지 못하는 외부라이브러리의 기준은 바로 

Spring이 관리하는 패키지 

이를 이해하기 위해서는 Spring이 component를 스캔하는 방식에 대해서 알아야 한다. 

 

Spring이 @Component를 스캔하는 방식

Spring이 @Component(혹은 @Service, @Repository, @Controller)가 붙은 클래스를 찾아 빈으로 등록하려면,
Spring이 스캔하는 패키지 내부에 클래스가 있어야한다. 

즉, @Component 스캔이 적용되는 범위는 @ComponentScan이 적용된 패키지 내부에 있는 클래스들뿐.

 

ObjectMapper는 다음 패키지에 존재한다. 

package com.fasterxml.jackson.databind;
 
따라서, ObjectMapper 같은 경우에는 Bean으로 선정해야 하는 것이다. 
 
 
 

근데 이제 MyComponent 처럼 내 패키지 안에 있는 사용자 정의 클래스라면, 

이 경우에는 Spring이 스캔하는 패키지 내부이면서, 개발자가 컨트롤 가능한 클래스라서

Component를 붙여야 하는 것이다. 

 

근데 @Component 대신 @Service, @Repository, @Controller를 사용할 수 있는가?
내부적으로 Component 어노테이션 있자나요 

결론부터 말하면 된다. 실행하면 오류 없이 잘 된다. 
@Component는 Spring에서 모든 빈을 스캔하고 등록하는 기본적인 어노테이션이니깐.

그러나 @Service, @Repository, @Controller는 각각 의미상으로 특정 계층을 명시하기 위한 어노테이션이다.

예를 들어,
@Service는 비즈니스 로직을 처리하는 서비스 클래스에,
@Repository는 데이터베이스 연동을 담당하는 DAO 클래스에 사용됩니다.
사실상, 이 어노테이션들은 @Component의 특수화된 형태이므로, 
의미에 맞는 어노테이션을 사용하는 것이 좋다고 생각합니다.

 

 

그럼 개발자가 생성한 Class에 @Bean은 선언이 가능할까?

안된다

 

@Bean과 @Component는 각자 선언할 수 있는 타입이 정해져있어 해당 용도외에는 컴파일 에러를 발생시킨다.

Component : Type

 

Bean : Method

 

그럼 한 번 외부 라이브러리에 Component 붙여서 오류를 내볼게여 제가 

@Component
public class ObjectMapperProvider  {

    private final  ObjectMapper objectMapper = new ObjectMapper();

    public ObjectMapper getObjectMapper() {
        return objectMapper;
    }
}

외부 라이브러리인 ObjectMapper에 Component를 붙여보고 

@Service
public class MyService {
    private final ObjectMapper objectMapper;

    public MyService(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    public void printMessage() {
        System.out.println(objectMapper);
    }
}

Service에서 주입받아 사용을 해보면 (애초에 ObjectMapper 제대로 쓰려면 객체 파싱 해야하는데 지금은 예시니까 생략)

 

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'com.fasterxml.jackson.databind.ObjectMapper' available

 

이렇듯 오류가 납니다. 

 

참고로

Component -> Bean 

Bean -> Component 모두

RuntimeException이다. 

 

왜냐면 스프링의 빈 주입은 애플리케이션 실행 시점에

1.  스프링이 클래스 경로를 스캔하고,
2. 이 과정에서 잘못된 어노테이션을 사용한 클래스를 빈으로 등록하려고 하면,
3. 해당 클래스가 빈으로 등록되지 않거나, 잘못된 빈 주입이 이루어져
=> 런타임 오류가 발생하게 된다. 

 

그러니까 애초에 잘 해주도록 하자 . . . 

 

 

 

 


https://jojoldu.tistory.com/27

 

@Bean vs @Component

Spring으로 개발을 하다보면 @Bean과 @Component를 언제 써야할지 헷갈릴때가 있다.둘다 목적이 명확하지 않은 Bean을 생성할때 사용하는 어노테이션인데 왜 2개로 나누어져있나 궁금했었는데, 박재성

jojoldu.tistory.com

 

최근댓글

최근글

skin by © 2024 ttuttak