스프링 빈 라이프사이클

라이프사이클

스프링의 빈은 스프링이 빈 생성, 주입, 소멸까지를 책임진다. 빈 생성부터 소멸까지의 라이프사이클을 다뤄보고자 한다.

라이프사이클 콜백

컨테이너가 빈의 라이프사이클을 관리하는데, 라이프사이클의 특정 시점에 커스텀 로직을 넣을 수 있도록 한 것이 라이프사이클 콜백이다.

라이프사이클 살펴보기

1. XML이나 어노테이션을 탐색하여 빈 정의를 스캔

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

SpringApplication.run()에서 어플리케이션컨텍스트를 만들고 빈 정의를 탐색하기 시작한다.

2. 빈 클래스의 인스턴스를 생성 - 생성자 호출

정의된 빈 인스턴스를 생성한다. 이때 생성자를 호출한다.

3. 빈 안에 주입되야할 프로퍼티들을 셋팅한다.

@Component
public class HelloBean implements ApplicationContextAware, InitializingBean {
    @Autowired
    WorldBean worldBean;
}

빈 안에 프로퍼티를 주입해야 하는데 프로퍼티에 해당하는 빈이 아직 생성되지 않은 경우 그 빈부터 생성해준다.
빈 간에 순환참조가 있으면 빈 생성과정에 에러가 발생하게 된다.

3. ~Aware 관련 콜백 호출

예를 들면 다음과 같은 것들이 있다.

ApplicationContextAware.setApplicationContext - 어플리케이션컨텍스트를 받을 수 콜백,
BeanClassLoaderAware.setBeanClassLoader - 클래스로더를 받을 수 콜백

이걸 써서 컨텍스트나 클래스로더를 따로 저장해둬야하는 상황이 어떤게 있을까....

이런 콜백들을 호출하려면 각 인터페이스를 implement해야한다.

package sample;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements ApplicationContextAware, BeanClassLoaderAware {

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        // do something
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // do something
    }
}

4. @PostContruct, InitializingBean.afterPropertiesSet(), init-method

셋은 프로퍼티 및 종속성 주입이 완료된 후 호출되는 점에서 동일하다.

@PostContruct는 JSR-250에서 정의한 어노테이션으로 스프링이 아닌 프레임워크에서도 사용할 수 있는 콜백이고, InitializingBean.afterPropertiesSet(), init-method는 스프링에서 제공하는 콜백이다.

InitializingBean.afterPropertiesSet()의 경우 InitializingBean 인터페이스를 implement하면 된다.

@Component
public class HelloBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("afterPropertiesSet() called");
    }
}

init-method의 경우 @Bean(initmethod="..")으로 등록한 메서드가 실행되게 된다.

실행 순서는 @PostContruct -> InitializingBean.afterPropertiesSet() -> init-method 이다.

세 가지 콜백을 각각 언제 사용해야 하는지를 명확히 구분할 수는 없다.

참고로 BeanPostProcessor.postProcessBeforeInitialization() 안에서 @PostContruct 가 호출된다.

5. BeanPostProcessor.postPRocessAfterInitialization()

기본 스프링부트 설정을 사용하는 경우 BeanPostProcessor를 따로 설정하지 않는 한 이 단계에서 하는 일은 없다.

이렇게 되면 빈을 사용할 수 있는 상태가 된다.
빈이 제거 될 때 설정할 수 있는 콜백도 생성과 비슷하다.

'개발 > Spring' 카테고리의 다른 글

[Java, Spring] Filter와 Interceptor의 차이  (0) 2020.05.22
[SpringMVC] CORS 처리  (2) 2020.03.31

+ Recent posts