@Component와 @Configuration 및 @Bean

서버란·2024년 11월 5일

스프링

목록 보기
3/4

1. @Component와 @ComponentScan

  • @Component는 Spring의 자동 구성(Automatic Configuration) 기능을 활용해, 특정 클래스를 Bean으로 등록하기 위해 사용합니다.
  • 클래스 자체를 Bean으로 등록하며, 개발자가 별도의 Bean 등록을 하지 않아도 자동으로 Spring이 Bean을 생성해 관리해줍니다.
  • @Component로 등록된 클래스는 @ComponentScan을 통해 스캔됩니다.
  • @ComponentScan은 지정된 패키지나 하위 패키지에서 @Component, @Service, @Repository, @Controller 등이 붙은 클래스를 스캔해 Bean으로 자동 등록합니다.

장점:

  • 자동화된 Bean 등록으로 개발자가 개별적으로 Bean을 정의하는 시간을 줄일 수 있습니다.
  • 특정한 비즈니스 로직을 구현하는 Service나 Repository 클래스에 적합합니다.

2. @Configuration과 @Bean

  • @Configuration은 Spring에서 Java 기반의 설정 클래스(Configuration Class)를 정의하기 위해 사용합니다.
  • @Configuration을 붙인 클래스 내부에 @Bean이 붙은 메서드를 정의해, 해당 메서드가 반환하는 객체를 Bean으로 등록할 수 있습니다.
  • @Bean은 개별 메서드 단위에서 Bean을 정의할 때 사용합니다. 이때 메서드가 아닌 메서드의 리턴 값이 실제로 Spring 컨테이너에 등록되는 Bean입니다.

중요한 차이점:

  • @Component는 클래스 전체를 Bean으로 등록하는 반면, @Configuration 클래스는 내부의 @Bean 메서드만을 통해 Bean을 정의하고 등록합니다.
  • @Configuration 클래스는 클래스 내 여러 개의 Bean을 묶어 하나의 설정 파일처럼 관리할 수 있게 해줍니다.

@Bean 메서드와 객체 공유

  • @Configuration 클래스에서 @Bean으로 정의한 메서드는 기본적으로 싱글톤(Singleton) 범위를 갖습니다.
  • Spring은 이 @Configuration 클래스를 프록시(Proxy) 객체로 관리하여, 동일한 @Bean 메서드가 여러 번 호출되더라도 항상 동일한 Bean 객체를 반환하도록 보장합니다.
  • 이와 같은 구조 덕분에, @Bean 메서드가 의존성을 주입하는 다른 @Bean을 호출하더라도 기존에 생성된 Bean을 재사용하여 효율성을 높입니다.

예시:

@Configuration
public class AppConfig {

    @Bean
    public ServiceA serviceA() {
        return new ServiceA(repository());
    }

    @Bean
    public Repository repository() {
        return new Repository();
    }
}

위의 예시에서 serviceA() 메서드는 repository() 메서드를 호출하여 ServiceA 객체를 생성하는데, 이때 Spring은 이미 생성된 Repository Bean을 재사용합니다.

왜 @Configuration이 @Component보다 유용한가?

  • @Configuration은 의존성 간의 관계를 보다 명확히 설정하고 관리하는 데 용이합니다.
  • Spring의 자동 구성 기능만으로는 해결하기 어려운 복잡한 객체 관계를 보다 명확히 설정할 수 있습니다.
  • 예를 들어, 외부 라이브러리나 서드파티 클래스를 Bean으로 등록해야 할 때, 직접 코드를 수정하지 않고도 @Configuration과 @Bean을 통해 원하는 방식으로 Bean을 설정하고 관리할 수 있습니다.

요약

  • @Component: 클래스 전체를 Bean으로 자동 등록하며, @ComponentScan을 통해 스캔되어 Spring 컨테이너에 추가됩니다. 비즈니스 로직 구현 클래스나 주로 단순한 Service/Repository 등에서 사용됩니다.
  • @Configuration: 설정 클래스로 사용되며, @Bean 메서드를 통해 여러 Bean을 선언하고 관리할 수 있습니다.
  • @Bean: 메서드에 선언하여 해당 메서드의 리턴 값을 Spring Bean으로 등록하며, 복잡한 객체 생성이나 외부 클래스와의 연동이 필요할 때 유용합니다.

참고사항:

Proxy와 Singleton 보장: @Configuration은 프록시 객체로 관리되며 @Bean 메서드가 여러 번 호출되어도 동일한 인스턴스를 반환하여 싱글톤을 보장합니다.
이렇게 구성하면 @Component와 @Configuration, @Bean의 사용 의도를 명확히 구분하고 각 특징을 최대한 활용할 수 있습니다.


Q1: @Configuration과 @Bean을 사용하는 것이 @Component를 사용하는 것보다 언제 유리할까요?

  • @Configuration과 @Bean이 유리한 상황은 복잡한 객체 생성이 필요하거나, 외부 라이브러리와의 연동이 필요한 경우입니다.
  • 예를 들어, 특정 Bean이 다른 Bean에 의존할 때, @Bean 메서드 내부에서 의존하는 Bean을 명시적으로 호출하여 생성 순서나 의존성을 관리할 수 있습니다.
  • 또한, 외부 API 또는 라이브러리 클래스는 Spring이 직접 관리할 수 없는 경우가 많아 @Component로 등록하기 어렵습니다. 이런 경우 @Bean을 이용해 Spring 컨테이너에 추가하는 것이 유리합니다.

Q2: @Bean 메서드를 통한 Bean 설정에서 싱글톤이 아닌 여러 인스턴스가 필요하다면 어떻게 설정할 수 있을까요?

  • 기본적으로 Spring은 모든 Bean을 싱글톤으로 관리하지만, 프로토타입 범위(Prototype Scope)를 사용하면 여러 인스턴스를 생성할 수 있습니다.
  • @Bean 메서드 위에 @Scope("prototype")을 추가하면, 해당 Bean이 필요할 때마다 새로운 인스턴스를 반환합니다.

예시 코드:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class AppConfig {

    @Bean
    @Scope("prototype")
    public ServiceA serviceA() {
        return new ServiceA();
    }
}

이 경우, serviceA() Bean을 여러 번 요청할 때마다 새로운 인스턴스가 반환됩니다. 다만, 주의할 점은 프로토타입 Bean은 싱글톤처럼 라이프사이클을 관리하지 않으므로 주입된 프로토타입 Bean의 라이프사이클을 직접 관리해야 할 수 있습니다.

Q3: @ComponentScan이 동작하지 않을 때 원인과 해결 방법은 무엇이 있을까요?

패키지 경로 설정 문제:

  • @ComponentScan이 스캔할 패키지를 제대로 지정하지 않으면 해당 패키지의 Bean이 등록되지 않을 수 있습니다.
  • @ComponentScan(basePackages = "com.example.package")와 같이 스캔할 패키지를 명시적으로 설정하는 것이 좋습니다.

Spring Boot 기본 패키지 위치:

  • Spring Boot에서는 @SpringBootApplication이 선언된 클래스의 패키지 위치를 기준으로 @ComponentScan이 작동합니다.
  • 만약 @SpringBootApplication이 com.example.main 패키지에 위치하고, Bean 클래스가 com.example.other 패키지에 있다면, @ComponentScan("com.example.other")로 추가적인 설정이 필요합니다.

특정 Annotation 누락:

  • @Service, @Repository, @Controller 등 특정 애노테이션이 누락된 경우, @ComponentScan에서 인식하지 못할 수 있습니다.
  • 등록할 클래스에 적절한 애노테이션이 붙어 있는지 확인해 보는 것이 좋습니다.

Java Config 또는 XML 설정 파일 충돌:

  • Java Config와 XML 설정 파일이 동시에 존재할 때 설정이 충돌할 수 있습니다.
  • 설정 파일을 여러 개 사용하는 경우, 특정 설정이 제대로 반영되지 않는지 확인하여 필요한 부분을 통합하거나 중복을 피하는 것이 좋습니다.

이러한 사항들을 점검하면 @ComponentScan이 동작하지 않을 때 원인을 찾고 문제를 해결할 수 있습니다.

profile
백엔드에서 서버엔지니어가 된 사람

0개의 댓글