[Spring] What - @Configuration, @Component의 차이점.

하쮸·2025년 4월 5일

Error, Why, What, How

목록 보기
18/63

1. 차이점.


1-1. @Configuration (Full Mode)

@Configuration
public class AppConfig {
    @Bean
    public SimpleBean simpleBean() {
        // 최초 한 번만 실행됨
        return new SimpleBean(); 
    }
    @Bean
    public SimpleBeanConsumer simpleBeanConsumer() {
        // simpleBean()을 호출해도, 프록시가 기존 싱글톤을 반환함
        return new SimpleBeanConsumer(simpleBean()); 
}
  • 위 코드를 보면, simpleBeanConsumersimpleBean를 의존성으로 갖고 있음.
    • 메서드 호출로 의존성을 주입하고 있음.
  • 겉보기에는 매번 new 키워드를 써서 새 인스턴스를 생성하는 것처럼 보이지만 실제 스프링은 그렇게 동작하지 않음.

  • @Configuration
    • @Configuration은 이 클래스가 스프링의 설정 정보를 담고 있음을 명시하며 항상 CGLIB 기반의 프록시를 생성하여 빈을 등록함.
      • 1개 이상의 @Bean을 사용하는 클래스의 경우 @Configuration을 사용하는 것을 권장함.
    • 생성하는 객체들을 스프링이 빈(Bean)으로 관리하라는 의미.
    • @Configuration이 사용된 클래스는 CGLIB 프록시를 기반으로 빈(Bean)을 싱글톤으로 유지함.
      • @Bean 메서드를 호출 하거나, @Bean 메서드가 또 다른 @Bean 메서드를 호출하더라도 항상 같은 인스턴스를 반환하게 해줌.
        이 점이 @Component와의 가장 큰 차이점.
    • 위 코드로 설명하자면.
      스프링 컨텍스트에 의해 관리되는 싱글톤 빈(Bean)이 생성됨.
      메서드를 여러 번 호출하더라도, 스프링이 생성한 동일한 빈(Bean)을 반환해줌.
  • 즉, @Configuration이 사용된 클래스 내부에 정의된 @Bean 메서드를 호출할 때 스프링 컨테이너에 해당 빈이 이미 존재하는지 확인하고 존재 한다면 그 빈을 반환해줌.
    • @Bean 메서드가 다른 @Bean 메서드를 호출하더라도, 매번 새로운 객체를 생성하는 것이 아니라 컨테이너에 존재하는 동일한 싱글톤 빈을 반환하도록 보장함.

1-2. @Component (Lite Mode)

  • @Component, @Service, @Repository, @Controller 등 @Configuration을 제외한 모든 스테레오타입 어노테이션은 Lite 모드로 작동함.
@Component // 또는 @Service, @Repository 등
public class AppConfig {
    @Bean
    public SimpleBean simpleBean() {
        return new SimpleBean(); 
    }
    @Bean
    public SimpleBeanConsumer simpleBeanConsumer(SimpleBean simpleBean) { // ⭐ 의존성을 인수로 주입받음
        // 스프링이 컨테이너의 싱글톤 SimpleBean을 인수로 넣어줌
        return new SimpleBeanConsumer(simpleBean); 
}

// 스프링의 의존성 주입(DI)을 통해 싱글톤 유지.
@Component
public class MyConfig {
    @Bean
    public ServiceA aService() {
        return new ServiceA();
    }

    @Bean
    public ServiceB bService() {
        return new ServiceB(aService());
    }
}

/*
bService() 내부의 aService() 호출은
스프링 컨테이너에서 관리되는 빈이 아니라, 그냥 new ServiceA()를 다시 만들어 반환함.
즉, ServiceA가 2번 생성되는 것. (싱글톤 깨짐)
*/
  • @Component

    • 개발자가 커스텀한 클래스를 빈(Bean)으로 등록하고자 하는 경우 @Component를 활용.
    • 스프링이 관리해야 할 컴포넌트(Component)라는 의미.
      • 즉, 스프링이 자동으로 빈(Bean) 등록해줌.
    • Lite 모드는 CGLIB 프록시를 생성하지 않고, 클래스 자체를 빈으로 등록함.
  • 즉, @Bean 메서드를 호출할 때는 싱글톤을 보장하지만, @Bean 메서드가 또 다른 @Bean 메서드를 호출할 때는 싱글톤이 아닌 새로운 객체를 반환함.

    • 따라서 @Bean 메서드가 다른 @Bean 메서드를 호출하면 이는 순수한 Java 메서드 호출이 됨.
      • @Bean 메서드가 호출될 때마다 새로운 인스턴스를 생성하게 되어 싱글톤이 보장되지 않고 스프링 컨테이너 통제 밖의 객체가 생성됨.
  • Lite 모드를 사용할 때는 빈 간의 의존성 주입이 필요한 경우 메서드 인수를 통해 주입받아야 함.

  • @Component의 기능을 @Configuration(proxyBeanMethods = false)로 동일하게 설정할 수 있음.
    (이러한 방식을 Bean 경량 모드 처리(bean light mode processing)라고 부르기도 함)

@Component
public static class Config {
    @Autowired
    SimpleBean simpleBean;

    @Bean
    public SimpleBean simpleBean() {
        return new SimpleBean();
    }

    @Bean
    public SimpleBeanConsumer simpleBeanConsumer() {
        return new SimpleBeanConsumer(simpleBean);
    }
}
  • 위 같은 방식으로도 싱글톤을 유지할 수 있지만 권장하진 않음.

2. 정리.

-@Component@Configuration
목적 및 역할- 일반 빈(Bean) 등록용 클래스.
- 일반적인 컴포넌트.
- 클래스 자체만 빈으로 등록됨.
- 빈(Bean) 등록 및 설정용 클래스.
- 설정 클래스(여러 Bean을 정의하는 클래스) 등록.
- @Bean 메서드를 통해 여러 빈을 등록 가능.
빈(Bean) 생성 방식- 클래스 자체를 빈(Bean)으로 등록.- @Bean 메서드를 통해 빈(Bean) 등록.
프록시 사용- 사용 X.- CGLIB 프록시 사용 (싱글톤 보장).
중복 호출 시- 새로운 객체를 반환할 수 있음.- 같은 객체를 반환함. (싱글톤 유지)
  • @Configuration

    • 여러 @Bean 메서드가 복잡하게 서로를 호출하며 의존하는 핵심 설정 클래스를 만들 때 사용.
  • @Component 계열

    • @Bean 메서드가 다른 @Bean 메서드를 호출할 필요가 없는 클래스나, 단순히 해당 클래스 자체를 스프링 빈으로 등록하고 싶을 때 사용. (대부분의 Service, Repository 등)

2. 참고.

profile
Every cloud has a silver lining.

0개의 댓글