개발스토리
@Bean, @Component, @Configuration 본문
이 세가지의 어노테이션 뭔지 너무 헷갈려~~ 알아보자잇!
Bean
Bean은 Spring IoC Container가 관리하는 자바 객체, Spring Bean Container에 존재하는 객체를 말한다.
Bean 컨테이너는 DI를 통해 Bean 객체를 사용할 수 있도록 해주는 역할을 한다.
스프링에서 Bean은 보통 Singleton으로 존재한다.
* Singleton : 어떠한 클래스가 최초로 한번만 메모리에 할당되고 그 메모리에 객체를 만들어 사용하는 패턴
또한 스프링의 DI Container에 의해 관리되는 POJO를 Bean이라고 부르고 이러한 Bean들이 스프링을 구성하는 핵심 요소이다.
스프링 빈 정리해보자잇~!
● Spring IoC 컨테이너(또는 DI 컨테이너)에 의해 생성 및 관리된다.
● POJO로써 Spring 애플리케이션을 구성하는 핵심 객체이다.
Spring Bean 구성요소를 알아보자
- class: Bean으로 등록할 Java 클래스
- constructor-arg: Bean 생성 시 생성자에 전달할 파라미터
- scope : Bean을 생성하기 위한 방법
- id : Bean 고유 식별자
- property : Bean 생성 시 setter에 전달할 인수
다른 Spring Bean 어노테이션 종류
개발을 하다보면 상당히 많은 클래스를 Bean으로 등록하게 된다. 옛날에는 이런것들을 모두 xml을 통해 Bean으로 등록하면서 상당히 시간이 소요되는 번거로운 작업을 했었다. 이러한 번거로움을 덜기 위해서 스프링에서는 어노테이션을 활용해 Bean을 등록해서 사용하는 방법을 제공하고 있다.
이제 스프링 Bean을 등록하는 방법에서 포스팅 제목의 세 가지 어노테이션을 사용한다.
@Bean 어노테이션과 @Configuration 어노테이션
Bean으로 등록하고자 한다면 @Bean 어노테이션을 활용하자.
import com.example.HeaderFilter;
import com.example.SessionInterceptor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter;
import java.util.Properties;
// 1개 이상 Bean을 등록하고 있음을 명시하는 어노테이션
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
...
@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
return new ResourceUrlEncodingFilter();
}
@Bean
public HeaderFilter createHeaderFilter() {
return new HeaderFilter();
}
@Bean
public FilterRegistrationBean<HeaderFilter> getFilterRegistrationBean() {
FilterRegistrationBean<HeaderFilter> registrationBean = new FilterRegistrationBean<>(createHeaderFilter());
registrationBean.setOrder(Integer.MIN_VALUE);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
@Bean
public BCryptPasswordEncoder createBCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
}
위 코드에서 볼 수 있듯이 많은 클래스들이 Bean으로 등록된다.
이러한 클래스들을 xml에 일일이 적어서 등록하는 것은 생산력에 큰 영향을 미친다.
그니까 편리하고 빠른 어노테이션을 통해 Bean을 등록하자!
하지만, 임의의 클래스를 만들어서 @Bean 어노테이션을 붙인다고 되는 것이 아니다. @Bean을 사용하는 클래스에는 반드시 @Configuration 어노테이션을 활용해서 해당 클래스에서 Bean을 등록하고자 함을 명시해주어야 한다.
위의 예제도 클래스 위에 @Configuration 어노테이션을 명시해서 해당 클래스에서 1개 이상의 Bean을 생성하고 있음을 명시하고 있다. 그렇기 때문에 @Bean 어노테이션을 사용하는 클래스의 경우 반드시 @Configuration과 함께 사용해야 한다.
추가로 @Configuration 없이도 @Bean만 사용해서 스프링 빈으로 등록이 가능하다. 대신에 메서드 호출을 통해 객체를 생성할 때 싱글톤을 보장하지는 않는다. 그렇기 때문에 스프링 설정 정보를 위해서는 반드시 @Configuration을 사용해주어야 한다.
그리고, 빈의 설정을 담당하는 @Configuration 어노테이션도 내부적으로 @Component를 가지고 있어 @Configuration이 붙은 클래스도 스프링의 빈으로 등록이 되는 것 역시 알아두면 좋다.
@Component 어노테이션
개발자가 직접 개발한 클래스를 Bean으로 등록하고자 하는 경우에는 @Component 어노테이션을 활용한다. 예를 들어, 파일 업로드 등을 처리하기 위해 직접 개발한 코드를 Bean으로 등록하고자 한다면 @Component 어노테이션을 사용하면 된다.
@Bean으로 등록할 수도 있지만 직접 개발한 클래스의 단위를 빈에 등록할 때는 @Component를 통해 해당 클래스를 빈으로 등록함을 노출하는 것이 좋다.
왜냐하면, @Component만 보면 해당 빈이 등록되도록 잘 설정되었는 지를 찾이 않고 확인할 수 있기 때문이다. 반면에 @Bean을 사용하면 해당 메서드를 찾는 번거로움이 생길 수 있다.
추가로 @Component를 이용한다면 메인 또는 앱 클래스에서 @ComponentScan으로 컴포넌트를 찾는 탐색 범위를 지정해주어야 한다. 하지만 스프링 부트를 쓴다면 @SpringBootConfiguration 하위에 포함되어 있어 별도의 설정이 필요 없다.
생각
그냥 신경안쓰고 쓰던 @SpringBootApplication이 사실 @ComponentScan, @Component를 상속받고 있었다.
스프링에서는 신경써서 설정을 해야 하는 번거로움이 있었지만 스프링 부트는 신경 안쓰고 어노테이션을 쓸 수 있어서
편리했었던 것이다. 스프링부트가 편리하지만 그냥 사용하는 것보다 스프링에서 무엇이 편리해졌고 무엇을 내재하고
있는 지 더 알아봐야 겠다.
'Spring & SpringBoot' 카테고리의 다른 글
Spring REST Docs 적용 (1) | 2021.11.11 |
---|---|
Spring REST Docs 도입 이유 (0) | 2021.11.11 |
Service와 ServiceImpl (1) | 2021.08.31 |
HikariCP가 뭘까?! (0) | 2021.08.30 |
Spring Security (1) | 2021.08.20 |