🌱스프링 빈(Bean)이란?
- 스프링(Spring) 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 합니다.
Spring의 특징에는 제어의 역전(IoC)이 있습니다.
제어의 역전이란, 간단히 말해서 객체의 생성 및 제어권을 사용자가 아닌 Spring에게 맡기는 것입니다.
지금까지는 사용자가 new연산을 통해 객체를 생성하고 메소드를 호출했습니다.
IoC가 적용된 경우에는 이러한 객체의 생성과 사용자의 제어권을 Spring에게 넘깁니다.
사용자는 직접 new를 이용해 생성한 객체를 사용하지 않고, Spring에 의하여 관리당하는 자바 객체를 사용합니다.
이 객체를 '빈(bean)'이라 합니다.
스프링 컨테이너란?
- 스프링 빈의 생명 주기를 관리하며, 생성된 스프링 빈들에게 추가적인 기능을 제공하는 역할을 하는 것을 스프링 컨테이너라고 합니다. IoC와 DI의 원리가 스프링 컨테이너에 적용됩니다.
개발자는 new 연산자, 인터페이스 호출, 팩토리 호출 방식으로 객체를 생성하고 소멸하지만, 스프링 컨테이너를 사용하면 해당 역할을 대신해 줍니다.
즉, 제어 흐름을 외부에서 관리하게 됩니다. 또한, 객체들 간의 의존 관계를 스프링 컨테이너가 런타임 과정에서 알아서 만들어 줍니다.
☘️스프링 빈(Bean) 등록 방법
Component Scan
@ (annotation) 사용 -> @Componenet
- 클래스 위에 @Component를 붙이면 스프링이 알아서 스프링 컨테이너에 빈을 등록합니다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
@Component 어노테이션 코드를 보면 위와 같이 ElementType.TYPE 설정이 있으므로 Class 혹은 Interface에만 붙일 수 있습니다.
-- ElementType.TYPE 설정에 대해서는 다음에 알아보겠습니다.
컴포넌트 스캔의 대상
@Component 외에 @Controller, @Service, @Repository, @Configuration는 @Component의 상속을 받고 있으므로 모두 컴포넌트 스캔의 대상입니다.
@Controller
- 스프링 MVC 컨트롤러로 인식된다.
@Repository
- 스프링 데이터 접근 계층으로 인식하고 해당 계층에서 발생하는 예외는 모두 DataAccessException으로 변환한다.
@Service
- 특별한 처리는 하지 않으나, 개발자들이 핵심 비즈니스 계층을 인식하는데 도움을 준다.
@Configuration
- 스프링 설정 정보로 인식하고 스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다. (물론 스프링 빈 스코프가 싱글톤이 아니라면 추가 처리를 하지 않음.)
Java 코드로 등록
클래스를 생성하고, 위에서 언급한 @Configuration 어노테이션을 활용하면 java 코드로 bean을 등록할수 있습니다.
@Configuration
public class AppConfig {
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
}
이때, 빈을 등록하기 위해 인스턴스를 생성하는 메소드 위에 @Bean를 명시하면 됩니다.
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
- @Bean은 위와 같이 ElementType 설정이 METHOD 혹은 ANNOTATION_TYPE이므로 메소드나 어노테이션에만 붙일 수 있습니다. 클래스에 붙일 수는 없습니다.
- @Configuration에는 @Component가 있으므로 컴포넌트 스캔이 대상이 되어 자동 스캔을 통해 빈 등록이 가능합니다.
수동 등록방법
거의 사용하지는 않지만, ApplicationContext를 호출하여 수동으로 설정 파일을 이용하여 빈을 수동으로 등록할 수도 있습니다.
public class Main {
public static void main(String[] args) {
final ApplicationContext beanFactory = new AnnotationConfigApplicationContext(AppConfig.class);
final AppConfig bean = beanFactory.getBean("appConfig", AppConfig.class);
}
}
@Bean 과 @Compoenet
- @Bean
- 개발자가 컨트롤이 불가능한 외부 라이브러리들을 Bean으로 등록하고 싶은 경우
에 사용됩니다. - 메소드 또는 어노테이션 단위에 붙일 수 있습니다.
- 개발자가 컨트롤이 불가능한 외부 라이브러리들을 Bean으로 등록하고 싶은 경우
- @Component
- 개발자가 직접 컨트롤이 가능한 클래스들의 경우에 사용됩니다.
- 클래스 또는 인터페이스 단위에 붙일 수 있습니다.
☀️ 참고
https://steady-coding.tistory.com/594