스프링 빈 라이프사이클
라이프사이클
스프링의 빈은 스프링이 빈 생성, 주입, 소멸까지를 책임진다. 빈 생성부터 소멸까지의 라이프사이클을 다뤄보고자 한다.
라이프사이클 콜백
컨테이너가 빈의 라이프사이클을 관리하는데, 라이프사이클의 특정 시점에 커스텀 로직을 넣을 수 있도록 한 것이 라이프사이클 콜백이다.
라이프사이클 살펴보기
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 |