초기화와 종료라는 라이프 사이클을 가짐생성되는 시점에 컨테이너를 초기화함close() 매서드를 사용해 종료, Bean 객체의 소멸
- 기본적으로 Spring의 ApplicationContext 구현은 초기화 프로세스에서
모든싱글톤 빈을 생성 및 설정- 따라서 Bean에 문제가 있을 경우 초기화 단계에서 알 수 있다는
장점이 존재- 만약 어떤 이유로, 특정 Bean이
늦은 초기화를 원한다면 다음과 같이 두 가지 방법이 존재
- xml에서 Bean을 등록시
lazy-init속성을 이용하여 초기화- Java Config에서 Bean을 등록시
@Lazy어노테이션을 이용
설정파일
전체를 Lazy-init
@Lazy @Configuration @ComponentScan(basePackages = "com.baeldung.lazy") public class AppConfig { @Bean public Region getRegion(){ return new Region(); } ...
특정 Bean을 Lazy-init@Bean @Lazy(true) public Region getRegion(){ return new Region(); }
Lazy init을 하더라도 해당 Bean을 다른 Bean이
참조한다면 그 시점에 초기화 됨
Bean 객체는 아래와 같은 라이프 사이클을 가지며 스프링 컨테이너에 의해 관리됨
스프링 컨테이너는 Bean 객체를 초기화하고 소멸하기 위해 빈 객체의 지정한 매서드를 호출
// 초기화 인터페이스
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
// 소멸 인터페이스
public interface DisposableBean {
void destroy() throws Exception;
}
afterPropertiesSet()와 destroy() 매서드를 구현하면 됨 // Client.java
// 초기화와 소멸에 해당하는 인터페이스를 상속 후, 각 매서드 재정의
public class Client implements InitializingBean, DisposableBean {
...
// 초기화 매서드 오버라이딩
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Client.afterPropertiesSet() 실행");
}
...
// 소멸 매서드 오버라이딩
@Override
public void destroy() throws Exception {
System.out.println("Client.destroy() 실행");
}
}
* 해당 코드를 수행하면 콘솔 화면에 매서드에서 정의한 `"Client.afterPropertiesSet() 실행"` 및 `"Client.destroy() 실행"`이 출력 됨
위의 두 인터페이스를 구현할 수 없거나, 두 인터페이스를 사용하지 않고 싶을 때 스프링 설정에서 직접 매서드를 지정 가능
initMethod 속성과 destoryMethod 속성을 사용해 사용할 매서드 이름을 지정// AppCtxWithprototype.java
@Configuration
public class AppCtxWithPrototype {
...
// 매서드의 이름을 지정해 초기화와 소멸 로직을 처리
@Bean(initMethod = "connect", destroyMethod = "close")
public Client2 client2() {
Client2 client = new Client2();
client.setHost("host");
return client;
}
}
// AppCtxWithprototype.java
@Configuration
public class AppCtxWithPrototype {
...
@Bean(destroyMethod = "close")
public Client2 client2() {
Client2 client = new Client2();
client.setHost("host");
// 초기화는 직접 수행, 소멸은 커스텀 매서드를 통해 수행
client.connect();
return client;
}
}
직접 매서드를 호출하여 초기화도 가능두 번 초기화 과정이 수행되지 않도록 주의initMethod 속성과 destroyMethod 속성에 지정한 매서드는
파라미터가 없어야 함
만약 파라미터가 존재할 경우, 스프링 컨테이너는Exception을 발생
싱글톤(singleton)의 범위를 가짐프로토타입(prototype)으로 지정시 Bean 객체를 매번 새롭게 생성@Scope 어노테이션을 @Bean 어노테이션과 함께 사용
- 프로토타입은 새로운 요청이 들어오면, 기존의 Bean을 바탕으로
복사해새로운 객체를 생성- 이렇게 만들어진 새로운 Bean은
스케줄링,멀티스레딩등에 사용이 됨// AppCtxWithprototype.java @Configuration public class AppCtxWithPrototype { // 해당 Bean 객체를 프로토 타입으로 지정 @Bean @Scope("prototype") public Client client() { Client client = new Client(); client.setHost("host"); return client; } // 해당 Bean을 명시저으로 싱글톤으로 지정 @Bean(initMethod = "connect", destroyMethod = "close") @Scope("singleton") public Client2 client2() { Client2 client = new Client2(); client.setHost("host"); return client; } }
// 프로토 타입의 경우
Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);
// client1 != client -> true
// 싱글톤의 경우
Client client1 = ctx.getBean("client", Client2.class);
Client client2 = ctx.getBean("client", Client2.class);
// client1 != client -> false
따르지 않음직접 해줘야 함