빈 생명주기
- 스프링 빈은 객체를 생성하고 의존관계 주입이 다 끝나야지만 필요한 데이터를 사용할 수 있는 준비가 완료되기 때문에, 초기화 작업은 의존관계 주입이 모두 완료되고 난 다음에 호출된다.
- 따라서 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주고, 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 보낸다.
객체의 생성과 초기화
- 생성자는 파라미터로 필수정보를 받고 메모리를 할당해서 객체를 생성하는 책임을 가지는 반면에, 초기화는 생성된 값들을 활용해서 외부 커넥션을 연결하는 등 무거운 동작을 수행한다.
- 따라서 생성자 안에서 초기화 작업을 하는 것보다 객체를 생성하는 부분과 초기화하는 부분을 명확하게 나누는 것이 유지보수 관점에서 좋다.
- 하지만 초기화 작업이 내부 값을 약간 변경하는 정도로 단순한 경우에는 생성자에서 한번에 처리하는 것이 좋을 수도 있다.
콜백 메서드
InitializingBean, DisposableBean 인터페이스 사용
public class NetworkTest implements InitializingBean, DisposableBean {
private String url;
public NetworkTest() {
System.out.println("생성자 호출")
}
public void setUrl(String url) {
this.url = url;
}
//서비스 시작시 호출
public void connect() {
System.out.println("connect: " + url);
}
public void call(String message) {
System.out.println("message = " + message);
}
//서비스 종료시 호출
public void disConnect() {
System.out.println("close: + " + url);
}
@Override
public void afterPropertiesSet() throws Exception {
connect();
call("초기화 연결 메시지");
}
@Override
public void destroy() throws Exception {
disConnect();
}
}
- InitializingBean은 afterPropertiesSet() 메서드로 초기화를 지원하고, DisposableBean은 destroy() 메서드로 소멸을 지원한다.
- 그러나 해당 인터페이스들은 스프링 전용 인터페이스로, 해당 코드가 스프링 전용 인터페이스에 의존하게 된다.
- 또한 메서드의 이름을 변경할 수 없어서 외부 라이브러리에 적용할 수 없다는 단점 때문에 거의 사용하지 않는다.
initMethod, destroyMethod 메서드 지정
- 설정 정보에 @Bean(initMethod = "init", destroyMethod = "close")과 같이 초기화, 소멸 메서드를 지정한다.
public class NetworkTest {
private String url;
public NetworkTest() {
System.out.println("생성자 호출");
}
public void setUrl(String url) {
this.url = url;
}
//서비스 시작시 호출
public void connect() {
System.out.println("connect: " + url);
}
public void call(String message) {
System.out.println("message = " + message);
}
//서비스 종료시 호출
public void disConnect() {
System.out.println("close: + " + url);
}
public void init() {
System.out.println("Network.init");
connect();
call("초기화 연결 메시지");
}
public void close() {
System.out.println("Network.close");
disConnect();
}
}
- 메서드 이름을 자유롭게 설정할 수 있고, 스프링 빈이 스프링 코드에 의존하지 않는다.
- 코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.
@PostConstruct, @PreDestroy 어노테이션 사용
public class NetworkTest {
private String url;
public NetworkTest() {
System.out.println("생성자 호출");
}
public void setUrl(String url) {
this.url = url;
}
//서비스 시작시 호출
public void connect() {
System.out.println("connect: " + url);
}
public void call(String message) {
System.out.println("message = " + message);
}
//서비스 종료시 호출
public void disConnect() {
System.out.println("close: + " + url);
}
@PostConstruct
public void init() {
System.out.println("Network.init");
connect();
call("초기화 연결 메시지");
}
@PreDestroy
public void close() {
System.out.println("Network.close");
disConnect();
}
}
- 자바 표준 기술로 스프링이 아닌 다른 컨테이너에서도 동작한다.
- 하지만 외부 라이브러리에 적용하지 못하므로 코드를 고칠 수 없는 외부 라이브러리를 초기화, 종료해야 하면 @Bean의 initMethod와 destroyMethod를 사용해야 한다.
'Spring > Spring' 카테고리의 다른 글
Lombok 생성자 어노테이션 (0) | 2022.07.07 |
---|---|
의존관계 주입 방법 (0) | 2022.03.03 |
객체지향 설계와 스프링 (0) | 2022.02.28 |
@Bean과 @Component (0) | 2022.01.27 |
스프링 컨테이너와 컴포넌트 스캔 (0) | 2022.01.20 |