지난 포스팅에서는 빈 라이프 사이클 중 스프링에서 제공하는 인터페이스를 이용해서 빈 객체의 초기화와 소멸을 실습해 보았습니다.
[Spring] 빈 라이프 사이클 : Bean 초기화, 소멸 (인터페이스)
컨테이너 초기화와 종료 스프링 컨테이너는 초기화, 종료 라이프사이클을 갖고 있습니다. 컨테이너 초기화 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppContext.class); 위 예제를
muscleking3426.tistory.com
이번 포스팅에서는 커스텀 메서드를 통해 빈 객체의 초기화와 소멸을 실습해 보겠습니다.
빈 객체의 초기화와 소멸을 스프링 인터페이스(InitializingBean, DisposableBean)를 통해 구현할 수 없거나 이 두 인터페이스를 사용하고 싶지 않은 경우에는 스프링 설정에서 직접 메서드를 지정할 수 있습니다.
@Bean 태그에서 initMethod 속성과 destoryMethod 속성을 사용해서 초기화 메서드와 소멸 메서드의 이름을 지정하면 됩니다.
public class Clinet2 {
private String host;
public void setHost(String host) {
this.host = host;
}
public void connect() {
System.out.println("Client2.connect() 실행");
}
public void send() {
System.out.println("Client2.send() 실행");
}
public void close() {
System.out.println("Client2.close() 실행");
}
}
Client2 클래스를 빈으로 사용하려면 초기화 과정에서 connect() 메서드를 실행하고, 소멸 과정에서 close() 메서드를 실행해야 한다면
아래와 같이 @Bean의 initMethod 속성과 destoryMethod 속성에 초기화와 소멸 과정에서 사용할 메서드 이름인 connect와 close를 지정해 주면 됩니다.
@Configuration
public class AppCtx3 {
@Bean
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
@Bean(initMethod = "connect", destroyMethod = "close")
public Client2 client2() {
Client2 client2 = new Client2();
client2.setHost("host2");
return client2;
}
}
메인 메서드를 실행해 볼까요?
public class Main {
public static void main(String[] args) {
//1. 컨테이너 초기화
AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx3.class);
//2. 빈 객체 로드 후, 사용하기
Client client = ctx.getBean(Client.class);
client.send();
//3. 컨테이너 종료
ctx.close();
}
}
위 메인 메서드를 실행하면 다음과 같은 결과가 나옵니다.
Client는 스프링 인터페이스인 InitializingBean과 DisposableBean에 정의된 초기화 호출 메서드와 소멸 호출 메서드가 실행되었고, Client2는 Appctx3 설정 클래스에 @Bean(InitMethod = "connect", destroy = "destroy" )를 통해 커스텀 된 메서드가 실행되었습니다.
설정 클래스는 자체는 자바 코드이므로 initMethod 속성 사용대신, @Bean 설정 메서드에서 직접 초기화를 수행해도 됩니다.
//1. initMethod로 빈객체 초기화하는경우
@Bean(initMethod = "connect", destroyMethod = "close")
public Client2 client2() {
Client2 client2 = new Client2();
client2.setHost("host2");
return client2;
}
//2. 설정 메서드에서 직접 초기화하는경우
@Bean(destroyMethod = "close")
public Client2 client2_1() {
Client2 client2 = new Client2();
client2.setHost("host2");
client2.connect();
return client2;
}
그럼, 이미 스프링인터페이스를 통해 빈 객체 초기화와 소멸을 구현하고 있는 객체를 커스텀 메서드를 통해 초기화, 소멸을 설정하면 어떻게 될까요?
@Bean
public Client client() throws Exception {
Client client = new Client();
client.setHost("host");
client.afterPropertiesSet();
return client;
}
Client 객체는 이미 InitializingBean 인터페이스를 상속받아 afterPropertiesSet() 메서드를 실행을 통해 초기화가 실행됩니다.
그런데, @Bean 설정에서 한번 더 afterPropertiesSet() 메서드를 호출해 주면 어떻게 될까요?
결과는 afterPropertiesSet가 2번 실행되었습니다. 즉 초기화가 2번 실행되는 것을 알 수 있습니다.
초기화 메서드가 2번 호출되지 않도록 주의해서 코드를 짜실 필요가 있습니다.
또한, @Bean의 initMethod 속성과 destroyMethod 속성에 지정한 메서드는 파라미터가 없어야 합니다. 이 두 속성에 지정한 메서드에 파라미터가 존재할 경우 스프링 컨테이너는 익셉션을 발생시킵니다.
public class Client2 {
private String host;
public void setHost(String host) {
this.host = host;
}
public void connect(String message) {
System.out.println(message + " Client2.connect() 실행");
}
public void send() {
System.out.println("Client2.send() 실행");
}
public void close() {
System.out.println("Client2.close() 실행");
}
}
초기화될 때 실행되는 connect 메서드에 message 변수를 파라미터로 설정하였습니다.
위와 같이 BeanCreationException 이 발생하는 것을 알 수가 있습니다.
따라서, @Bean의 initMethod, destroyMethod를 통해 메서드를 수행한다면 해당 메서드는 파라미터가 없어야 하는 것에 주의를 해야 합니다.
'Spring' 카테고리의 다른 글
[Spring] AOP 프로그래밍 - 프록시(Proxy) 객체 (0) | 2024.01.30 |
---|---|
[Spring] 빈 객체의 생성과 관리범위 (0) | 2024.01.29 |
[Spring] 빈 라이프 사이클 : Bean 초기화, 소멸 (인터페이스) (1) | 2024.01.25 |
[Spring] AOP 프로그래밍이란 ? (1) | 2024.01.25 |
[Spring] Autowired 와 수동 Bean 등록 (@Qualifier) (0) | 2024.01.24 |