spring

[spring] @Bean과 @Component

엄지성 2024. 8. 4. 20:03

스프링에는 `@Bean`과 `@Component`가 존재한다.

그리고 이 두 개의 어노테이션이 사용되는 것을 개발하다 보면 자주 발견할 수 있다.

그래서 이 두개의 궁금증이 생길 수 있어 한번 알아보자.


이것의 목적

사실 두개의 어노테이션이 똑같다고 생각할 수 있을 만큼 목적이 비슷하다.

이 어노테이션들의 목적은 IoC 컨테이너에 빈으로 등록하고 싶을 때 사용하는 어노테이션들이다.

하지만 목적이 똑같다고 사용하는 방법이 동일한 것은 아니기 때문에 이것에 대한 궁금증을 한번 해소해 보는 것이 좋을 것 같다.


@Bean

이 어노테이션의 경우는 개발자들이 컨트롤하지 못하는 외부 라이브러리같은 것을 IoC 컨테이너에 빈으로 등록하고 싶을 때 사용하는 것이다.

 

이 어노테이션이 사용하는 타겟은

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})

와 같은 타겟은 함수 또는 외부 라이브러리로 추가한 어노테이션과 같은 경우에 사용하는 어노테이션이다.

 

사실 `@Bean` 어노테이션 같은 경우는 반드시 `@Configuration` 어노테이션을 활용하여 사용하는 것은 강조한다.

왜냐하면 Configuration 어노테이션에는 중요하고 특별한 기능이 존재하기 때문이다.

그 이유는 `@Component` 아래에 리마인드 하겠습니다.

 


@Component

그러하면 이 어노테이션은 위에 설명한 Bean 어노테이션과 어떤 차이점을 가지고 있나?

차이점은 위에서는 개발자가 컨트롤하지 못하는 것에 사용을 하였다면 이번은 개발자가 컨트롤할 수 있는 클래스를 빈으로 등록시키기 위한 어노테이션이다.

 

이 어노테이션은 우리가 자주 볼 수 있는 `@Service`, `@Repository`, `@RestController` 등에 자세히 보면 존재하여 자연스럽게 빈에 등록시켜 주는 존재이다.

 

이 어노테이션이 사용하는 타겟은

@Target(ElementType.TYPE)

클래스, 인터페이스, 열거형 등에 사용할 수 있고 타겟에 맞게 사용하면 되고

만약에 서로 맞지 않은 타겟에 설정을 하고 사용을 한다면 컴파일 시에 에러가 뜰 수 있다.


@Configuration 사용을 강조하는 이유

위에서 Configuration 어노테이션은 특별한 기능이 있다고 앞서 말하였다.

그 기능을 말하기 앞서 잠시 어노테이션 설명을 하자면

위에 사진을 보면 Configuration에는 Component가 존재하는 것을 알 수 있다.

그래서 Configuration을 사용하여도 빈에는 등록이 아무 문제가 생기지 않는 것을 알 수 있다.

그러면 왜? 어노테이션을 굳이 따로 만들었을까?라는 의문이 생길 것이다.

 

그것은 CGLib으로 프록시 패턴을 적용하여 수동으로 등록하려는 스프링 빈이 반드시 싱글톤으로 생성되는 것을 보장하기 위한 것이다.

더보기

CGLib란?

 

CGLIB(Code Generator Library): 코드 생성 라이브러리로서 런타임에 동적으로 자바 클래스의 프록시를 생성해주는 기능을 제공한다. 인터페이스가 아닌 클래스에 대해서 동적 프록시를 생성할 수 있다.

CGLIB는 타겟에 대한 정보를 직접적으로 제공받아 바이트 코드를 조작하여 프록시를 생성하여 리플렉션을 사용하는

JDK Dynamic Proxy보다 성능이 좋다.  이것의 장점은 인터페이스가 필요 없이 단순히 클래스만으로도 프록시 객체를 동적으로 생성이 가능한 것이 장점이다.


정리

이것으로 `@Bean`과 `@Component`를 소개해보았다.

Bean 어노테이션 같은 경우는 지금까지 설명한 것보다 더욱 딥하여서 여기까지만 설명하였다.

 

그래서 Bean과 Component타겟뿐만 아니라 사용하는 의미가 다른 어노테이션이니 목적이 비슷하다고 헷갈려하지 않으면 좋을 것 같다.

 

'spring' 카테고리의 다른 글

[spring] 스프링 시큐리티? 무슨 역할을 할까  (0) 2024.08.11
[spring] IoC와 DI?  (0) 2024.06.07
[spring] @Controller VS @RestController 차이점  (0) 2024.04.03