IT 개발 라이프/Back_End

@Component와 @Configuration란?

10Biliion 2024. 12. 26. 15:57

Spring Framework에서 자주 사용되는 두 가지 중요한 애노테이션이 있습니다: @Component@Configuration. 이 두 애노테이션은 모두 빈(Bean)을 정의하는 데 사용되지만, 사용하는 목적과 동작 방식에서 큰 차이가 있습니다. 이 글에서는 각각의 애노테이션에 대해 상세히 알아보고, 어떤 상황에서 어떤 애노테이션을 선택해야 하는지 명확히 이해할 수 있도록 설명하겠습니다.


1. @Component란?

@Component는 Spring에서 관리되는 일반적인 빈(Bean)을 정의하기 위해 사용됩니다. Spring 컨테이너는 @Component가 붙은 클래스를 스캔하여 자동으로 빈으로 등록합니다.

주요 특징:

  1. 자동 감지:
    • @Component는 클래스 레벨에서 선언되며, Spring의 컴포넌트 스캔(component scan)에 의해 자동으로 감지됩니다.
    • @ComponentScan 또는 @SpringBootApplication이 있는 패키지와 그 하위 패키지에서 스캔됩니다.
  2. 기본 사용 예:
@Component
public class MyComponent {
    public void doSomething() {
        System.out.println("Doing something in MyComponent");
    }
}
  1. 주요 애노테이션의 기반:
    • @Repository, @Service, @Controller는 모두 @Component의 특화된 형태입니다.
    • 각 애노테이션은 역할에 맞는 추가적인 기능을 제공합니다.
      • @Repository: 데이터 접근 계층(DAO)에서 사용, 예외 변환 기능 포함.
      • @Service: 서비스 계층에서 사용, 특별한 추가 기능은 없음.
      • @Controller: Spring MVC의 컨트롤러에서 사용, HTTP 요청 처리에 적합.
  2. 의존성 주입:
    • @Autowired를 사용하여 @Component로 정의된 빈을 주입할 수 있습니다.
@Component
public class MyService {
    public String getMessage() {
        return "Hello from MyService!";
    }
}

@Component
public class MyController {
    private final MyService myService;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

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

2. @Configuration란?

@Configuration은 Java 기반의 설정 클래스에서 사용되며, Spring 컨테이너에서 관리할 빈들을 정의하는 데 사용됩니다. 이 애노테이션은 특히 명시적으로 빈을 정의하고 설정해야 할 때 유용합니다.

주요 특징:

  1. 설정 클래스:
    • @Configuration은 클래스를 설정 파일로 지정합니다. 이 클래스 내부에서 @Bean을 사용해 하나 이상의 빈을 정의합니다.
  2. @Bean 등록:
    • @Configuration 클래스는 메서드에 @Bean 애노테이션을 사용하여 직접 빈을 생성하고 반환할 수 있습니다.
@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyService();
    }

    @Bean
    public MyController myController(MyService myService) {
        return new MyController(myService);
    }
}
  1. 싱글톤 보장:
    • @Configuration 클래스는 @Bean으로 정의된 빈들이 싱글톤임을 보장합니다.
    • 내부적으로 CGLIB 프록시를 사용하여 메서드 호출을 관리합니다.
@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        System.out.println("Creating MyService instance");
        return new MyService();
    }

    @Bean
    public AnotherService anotherService() {
        System.out.println("Using MyService in AnotherService");
        return new AnotherService(myService());
    }
}

위 코드에서 myService()는 한 번만 호출됩니다.

  1. 외부 설정 파일 연계:
    • @Configuration 클래스는 외부 설정 파일(properties, YAML 등)과 함께 사용되어 동적으로 빈을 구성할 수 있습니다.
@Configuration
@PropertySource("classpath:application.properties")
public class AppConfig {

    @Value("${app.name}")
    private String appName;

    @Bean
    public AppInfo appInfo() {
        return new AppInfo(appName);
    }
}

3. @Component와 @Configuration의 차이점

특징 @Component @Configuration
주요 목적 일반적인 빈 정의 설정 클래스 및 @Bean 기반 빈 정의
빈 등록 방식 자동 등록 (컴포넌트 스캔) 명시적 등록 (@Bean 메서드)
싱글톤 보장 빈 자체에서 보장하지 않음 CGLIB 프록시를 통해 보장
사용 위치 일반 클래스 설정 클래스
주요 사용 사례 비즈니스 로직, 서비스 클래스 복잡한 빈 설정, 외부 라이브러리 빈 등록

4. 언제 사용해야 할까?

@Component를 사용할 때:

  • 클래스가 간단한 비즈니스 로직을 수행하거나 특정 역할을 수행하는 서비스 또는 DAO일 때.
  • Spring 컨테이너가 자동으로 빈을 스캔하고 등록하도록 하고 싶을 때.

@Configuration을 사용할 때:

  • 복잡한 빈 설정이 필요하거나 외부 라이브러리를 Spring 컨텍스트에 통합해야 할 때.
  • 명시적인 빈 정의와 세밀한 제어가 필요한 경우.
  • @PropertySource, @Value와 함께 외부 설정 파일을 처리해야 할 때.

5. 함께 사용하기

실제 프로젝트에서는 @Component@Configuration을 혼합하여 사용하는 경우가 많습니다. 다음은 두 애노테이션을 함께 사용하는 예입니다.

@Component
public class ServiceA {
    public String getMessage() {
        return "Hello from ServiceA!";
    }
}

@Configuration
public class AppConfig {

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

public class ServiceB {
    private final ServiceA serviceA;

    public ServiceB(ServiceA serviceA) {
        this.serviceA = serviceA;
    }

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

결론

  • @Component는 단순하고 자동화된 빈 정의를 위해, @Configuration은 명시적이고 세밀한 설정이 필요할 때 사용됩니다.