본문 바로가기
web/SpringBoot

[REST API] @Configuration / @Component

by 뽀리님 2023. 11. 14.

개발을 하다보면 @Bean 등록을 할 때 @Configuration 과 @Component 중에 뭘써야 할지 몰라 정리해본다.

 

일단 내가 알고있는 간단한 개념은

@Configuration

- 개발자가 직접 제어가 불가능한 외부 라이브러리 또는 설정을 위한 클래스를 Bean으로 등록할 때 사용

- Method 에 @Bean이 있어야함.(짝꿍쓰)

- Spring 컨테이너(Ioc)에 의해 처리

 

@Component 

- 개발자가 직접 작성한 클래스를 빈으로 등록하고 싶을 사용
-
다른 클래스에서 Bean으로 불러 사용이 가능함

- CompoentScan 대상임을 표시하고, Spring 컨테이너에 등록

 

 

얼핏보면 비슷해보이지만, 사실 알고보면 차이가 있다.

가장 큰 차이는 @Bean 등록하는 방법이 다르다는 것이다.

 

2개의 예제를 보자

// @Configuration 사용 예제
@Configuration
public static class Config {

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

    @Bean
    public SimpleBeanConsumer simpleBeanConsumer() {
        return new SimpleBeanConsumer(simpleBean());
    }
}

 

// @Component 사용 예제
@Component
public static class Config {

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

    @Bean
    public SimpleBeanConsumer simpleBeanConsumer() {
        return new SimpleBeanConsumer(simpleBean());
    }
}

 

 

@Configuration 애노테이션과 @Component 애노테이션은 동작하는 방식이 비슷해 보인다.

@Configuration @Component 포함하기 때문이다.

 

둘다 애노테이션이 기술된 클래스를 빈으로 등록시키며, 내부의 @Bean 애노테이션이 붙은 클래스들을 스프링컨텍스트에 등록시킨다.

 

위의 예제 소스에서는 서로 결과가 다르다. 예제마다 simpleBeanConsumer() 메소드 내에서 simpleBean() 호출하는 부분이 있는데 부분이 동작하는 방식이 다르기 때문이다.

 

 

 

@Configuration 스프링 빈으로 등록할 객체를 싱글톤으로 반환

스프링 컨테이너(Ioc)는 싱글톤 레지스트리로써, 싱글톤 객체를 관리하는 싱글톤 컨테이너 역할을 한다.

(싱글톤 -> 프로그램 내에서 하나의 객체만 존재하고 여러 부분에서 해당 객체를 공유하여 사용)

 

요청은 굉장히 많은 요청으로 이루어지기 때문에 싱글톤이 아닌 프로토타입으로 스프링 빈을 반환하게 된다면, 요청마다 객체를 생성하여 메모리가 터질 있다.

 

번째 예제(@Configuration) 의 메소드에서는 simpleBean() 호출시 스프링 컨텍스트(Ioc)에 등록되어 있는 SimpleBean 클래스를 반환하지만,

 

두 번째 예제(@Component) 에서는 순수 메소드 호출을 한것 처럼 스프링 컨텍스트에 등록되어 있는 빈이 반환되는 것이 아니라 새로 생성된 빈이 반환된다.(싱글톤이 보장되지 않음)

 

즉, 스프링 컨테이너(Ioc) 에 등록된 빈을 반환하느냐, 안하느냐의 차이라 할 수 있겠다.

 

만약 @Component 사용하는 경우에도 @Configuration 처럼 작동하게 하고 싶다면 아래와 같이 수정하면된다.

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

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

    @Bean
    public SimpleBeanConsumer simpleBeanConsumer() {
        return new SimpleBeanConsumer(simpleBean);
    }
}

 

 

 

가능하면 @Configuration을 사용하라는데?

@Configuration classes currently always get enhanced via CGLIB.

  • @Configuration 을 사용시 CGLIB 처리를 통해 성능 향상을 기대할 수 있다고 했다.(스프링 개발자 오피셜)
  • 내부에서 호출된 @Bean  붙은 메소드를 호출하는 경우, 이미 등록된 Bean 있으면 컨테이너에서 꺼낸다. 없는 경우 등록하고 반환

 

사실 뭘쓰는지간에, 잘만쓴다면 문제는 없다. 취향의 차이일뿐 정답은 없다고 생각한다.

단지, 개발하다보니 2개의 차이점이 궁금해서 찾아보다가 CGLIB(Code Generator Library) Proxy 패턴에 대해 알게되었는데, 이것까지 정리 하려니 복잡해서 이건 나중에 정리해보도록 하겠다.

 

 

참조 :

https://hyune-c.tistory.com/entry/Component-vs-Configuration

https://9327144.tistory.com/entry/Spring-Configuration%EA%B3%BC-Component-%EA%B7%B8%EB%A6%AC%EA%B3%A0-Bean

https://unluckyjung.github.io/spring/2021/06/11/Spring-Configuration-VS-Component/

https://m.blog.naver.com/sthwin/222131873998

 

https://memodayoungee.tistory.com/151

https://huisam.tistory.com/entry/springAOP