외부에서 값을 세팅하고 나서 초기화를 호출해야 할 때가 많다.
스프링 빈은 객체 생성 -> 의존관계 주입의 라이프 사이클을 가진다.(생성자 주입 제외)
스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려준다. 또한 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 준다.(싱글톤에 한함)
스프링 빈의 이벤트 라이프 사이클
스프링 컨테이너 생성 > 스프링 빈 생성 > 의존관계 주입(수정자 주입) > 초기화 콜백 > 사용 > 소멸전 콜백 > 스프링 종료
초기화 콜백 : 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
소멸전 콜백 : 빈이 소멸되기 직전에 호출
객체의 생성과 초기화는 분리하는 것이 좋다.
생성자 안에서 무거운 초기화 작업을 동시에 하는 것 보다는 객체를 생성하는 부분과 초기화 하는 부분을 명확하게 나누는 것이 유지보수 관점에서 좋다.
스프링은 다음 3가지 방식으로 초기화와 종료를 지원해 준다.
인터페이스(InitializingBean, DisposableBean)
단점
코드가 스프링 전용 인터페이스에 의존해야 한다.
초기화, 소멸 메서드의 이름을 변경할 수 없다.
내가 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.
지금은 더 나은 방법이 있으므로 잘 사용하지 않는다.
설정 정보에 초기화 메서드, 종료 메서드 지정
설정 정보에 @Bean(initMethod = "init", destroyMethod = "close") 처럼 초기화와 소멸 메서드를 지정할 수 있다.
장점
메서드 이름을 자유롭게 줄 수 있다.
스프링 빈이 스프링 코드에 의존하지 않는다.
코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.
외부 라이브러리는 종료메서드가 대부분 close나 shutdown으로 되어있다.
@Bean으로 등록할 때, destroyMethod 속성은 기본값으로 그 종료 메서드를 추론하여 호출해준다.
이 기능이 싫다면 destroyMethod=""로 해주면 된다.
@PostConstruct, @PreDestroy 어노테이션 지원
장점
스프링에서 권고하는 방식이다.
javax(자바 표준)이므로 스프링이 아닌 다른 컨테이너에서도 적용이 된다.
컴포넌트 스캔과 잘 어울린다.(빈 등록을 수동으로 안해줘도 됨)
단점
외부 라이브러리에 적용할 수 없다. > 외부 라이브러리에 쓰려면 2번을 쓰자