스프링 빈은 IoC 컨테이너가 관리하는 자바 객체로서 컨테이너에 의해 생명주기가 관리되는 개체를 의미합니다.
스프링에서는 해당 빈을 생성하는 방법으로 크게 2가지가 있습니다.
Component 어노테이션과 Bean 어노테이션을 사용하는 방법이죠. 각각의 방법이 무슨차이가 있고 어떻게 사용해야 되는지 살펴보도록 하겠습니다.
@Bean
개발자가 컨트롤이 불가능한 외부라이브러리들을 Bean으로 등록하고 싶은 경우에 사용되는 방법입니다. 사용 예시는 다음과 같습니다.
Json 파싱을 해주는 ObjectMapper 클래스를 사용하려면 다음과 같이 Gradle 의존성을 설정해줘야 합니다.
그러고 나서 external library의 jackson-databind 패키지를 까보면 모듈 패키지 안에 ObjectMapper 클래스가 생긴 것을 볼 수 있습니다. 해당 클래스를 확인해보면
다음과 같이 아무 어노테이션도 선언이 안되어 있는것을 확인할 수 있습니다. 순수 자바 코드로된 파일에 해당합니다.
이와 같이 외부 라이브러리에 해당하는 클래스를 스프링 빈으로 등록하고 싶을 때는 아래와 같이 작성해주면 됩니다.
코드를 보시면 아시겠지만 @Bean 어노테이션은 objectMapper()라는 메서드 레벨에 붙어 있는 것을 알 수 있습니다.
@Bean 어노테이션의 타겟이 아래와 같이 'ElementType.Method' 이기 때문에 클래스 레벨에서는 쓸 수 없기 때문입니다.
그렇다면 Configuration이 선언된 BeanGenerator 클래스는 왜 필요한걸까요? 그 이유는 Configuration이 특별한 부가기능을 제공해주기 때문입니다.
Configuration 어노테이션 안에는 @Component가 다음과 같이 선언되어있습니다.
다시 말하면 Configuration 어노테이션이 붙어 있는 클래스 역시 스프링 빈으로 등록되게 됩니다. 그러면 Component 어노테이션을 쓰면 되는것 아닐까요? 따로 Configuration을 만든 이유는 뭘까요?
바로 CGLIB으로 프록시 패턴을 적용하여 수동으로 등록한 스프링 빈이 반드시 싱글톤으로 생성됨을 보장하기 위해서입니다.
다음과 같이 AAA와 BBB 빈이 objectMapper을 주입받아서 생성되는 빈이라고 가정해봅시다.
만약 Configuration 어노테이션이 없다면 AAA와 BBB 각각에 들어가는 ObjectMapper는 서로 다른 객체들이
주입될것입니다. 하지만 Configuration 어노테이션을 사용하여, 테스트 코드를 통해 각 객체들을 살펴보면
다음과 같이 @5b78fb1 이라는 동일한 객체 주소를 지니고 있는것을 확인할 수 있습니다. Configuration 어노테이션은 proxyBeanMethod라는 설정이 true로 기본값으로 설정되어 있습니다. 만약 이것을 false로 설정하게 되면 GCLIB이라는
프록시 패턴을 사용하지 않게되고, 이는 곧 동일한 빈을 호출할때 마다 다른 객체가 반환 됨을 의미하게 됩니다.
아까와 같은 예시 코드에서 Configuration 설정만 바꾸어 보도록 하겠습니다.
그러고 나서 테스트 코드를 통해 AAA와 BBB안에 있는 objectMapper 객체를 살펴보면 아래와 같이 서로 다른
객체가 생성된 것을 알 수 있습니다.
정리하자면, @Bean 어노테이션이 붙은 메서드와 @Configuration이붙은 클래스를 함께 써야 되는 이유는 수동으로 생성된 스프링 빈의 싱글톤 패턴을 GCLIB이라는 프록시 패턴을 활용하여 보장해주기 때문입니다.
@Component
컴포넌트 어노테이션은 스프링을 사용하다보면 흔히들 쓰는 @Controller, @Service, @Repository 안에 붙어 있는 어노테이션 입니다. Component 어노테이션은 Bean과 다르게 Target값이 Element.TYPE으로 설정되어 있어서 클래스, 인터페이스, 열거형 모두에 붙여 사용할 수 있습니다.
컴포넌트 어노테이션은 개발자가 작성한 클래스위에 @Component 또는 이를 함유하고 있는 @Controller, @Service와 같은 어노테이션을 붙여주기만하면 수동으로 빈을 등록하지 않더라도 컴포넌트 스캔을 통하여 해당 컴포넌트를 빈으로 등록해주게 됩니다.
사용 방법을 예시로 들자면
다음과 같이 작성한 클래스 위에 Component를 가지고 있는 Controller 어노테이션을 선언해주기만 하면
해당 빈을 생성해주는 것을 알 수 있습니다. Bean 등록 방법에 비해 간단하고 편리한 특징을 지니고 있습니다.
이상으로 Component와 Bean에 대해 살펴보았습니다.
글 읽어주셔서 감사합니다!
참고 블로그
https://mangkyu.tistory.com/75
[Spring] 빈 등록을 위한 어노테이션 @Bean, @Configuration, @Component 차이 및 비교 - (1/2)
기존의 Spring MVC에서는 xml을 활용하여 Bean을 등록하고 있었다. 하지만 프로젝트의 규모가 커짐에 따라 사용하는 요소들을 xml에 등록하는 것이 상당히 번거로워 져서 어노테이션(Annotation, @)를 활
mangkyu.tistory.com
https://jojoldu.tistory.com/27
@Bean vs @Component
Spring으로 개발을 하다보면 @Bean과 @Component를 언제 써야할지 헷갈릴때가 있다.둘다 목적이 명확하지 않은 Bean을 생성할때 사용하는 어노테이션인데 왜 2개로 나누어져있나 궁금했었는데, 박재성
jojoldu.tistory.com
'Spring' 카테고리의 다른 글
생성자 주입 방식을 써야하는 이유 (0) | 2023.05.03 |
---|---|
AOP에 대하여 (2) | 2023.04.19 |
BeanFactory와 ApplicationContext의 차이점 (0) | 2023.02.21 |
스프링 빈의 쓰레드 안정성에 대하여 (0) | 2023.02.21 |
스프링 시큐리티 아키텍처에 대하여 (0) | 2023.01.29 |