스프링 빈

스프링 컨테이너에 의해 관리되는 인스턴스

관심사 분리

Bean Defiinition

bean에 대한 configuration metadata로 IoC 컨테이너에서 스프링 빈마다 BeanDefiniiton으로 정의됨

bean definition

빈 등록 방법

Java Config와 Annotation Config는 컴포넌트 스캔에 의해 등록됨

Java Config

  1. @Configuration

스프링 빈들을 등록할 configuration 클래스 명시

@Configuration 클래스 또한 스프링 빈으로 등록됨

주요 속성

  1. @Bean

스프링 빈으로 등록할 클래스 명시

@Configuration 클래스 내부에서 선언하는 것을 권장

메서드, 어노테이션에만 적용 가능

보통 외부 라이브러리 객체를 스프링 빈으로 등록할 때 사용

주요 속성

Annotation

  1. @Component

스프링 빈으로 등록할 클래스 명시

클래스에만 적용 가능

애플리케이션 내의 객체를 스프링 빈으로 등록할 때 사용

  1. @ComponentScan

자동으로 컴포넌트를 찾아 스프링 빈으로 등록하는 기능을 가진 어노테이션

Component Scan 대상

기본 범위

주요 속성

빈 스코프

singleton (기본 값)

prototype

request, session, application, websocket scope는 WebApplicationContext에서만 유효함

request

session

application

websocket

Bean LifeCycle

test

출처

Bean LifeCycle Callback

IoC 컨테이너가 빈 생성, 소멸할 때 호출하는 콜백

인스턴스 생성, 의존성 주입 후 콜백 호출

  1. 콜백 인터페이스 구현
  2. 콜백 메서드 지정
    • 주로 @Bean으로 스프링 빈 등록 시 사용
    • initMethod, destroyMethod 속성
  3. @PostConstruct, @PreDestroy 콜백 어노테이션 선언
    • 클래스 내 콜백을 수행하는 메서드에 선언

BeanPostProcessor

용도

public interface BeanPostProcessor {

    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

postProcessBeforeInitialization : 빈 초기화(@PostConstruct 등) 이전 호출

postProcessAfterInitialization : 빈 초기화 후 호출

Custom BeanPostProcessor

BeanPostProcessor 구현 후 Bean 등록

public class CustomBeanPostProcessor implements BeanPostProcessor {
    ...
}

특징

BeanFactoryPostProcessor

Bean Definition을 조작할 수 있는 hook으로 IoC 컨테이너가 빈을 생성하기 이전 시점에 동작함

Dependency Injection

Injection Annotation

@Autowired

@Inject

@Resource

Constructor Injection

객체 생성 시점에 생성자를 통해 의존성 주입을 받는 방법(권장)

final 키워드 선언 권장

private final LocalService;

public LocalController(LocalService localService) {
    this.localService = locaService;
}

Field, Property Injection

객체를 생성한 뒤 필드에 의존성 주입을 받는 방법

권장하지 않는 이유

@Autowired 
private LocalService localService;

Method injection

객체를 생성한 뒤 메서드를 통해 의존성 주입을 받는 방법

용도

권장하지 않는 이유

private LocalService localService;

@Autowired
public void SetLocalService(LocalService localService) {
    this.localService = localService;
}

Injection Priority

IoC 컨테이너는 의존성 주입 시 타입을 기반으로 함

동일한 타입의 빈이 여러 개 있을 경우 -> NoUniqueDefinitionException 발생

해결 방안

@Primary

@Primary
@Component
public class FirstLocalService implements LocalService

@Component
public class SecondLocalServie implements LocalService

@Qualifier

public LocalController(@Qualifier("secondLocalService") localService) {
    this.LocalService = localService;
}

@Named

@Inject
public LocalController(@Named("secondLocalService") localService) {
    this.LocalService = localService;
}