초기화
와 종료
라는 라이프 사이클을 가짐생성되는 시점에 컨테이너를 초기화
함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
따르지 않음
직접
해줘야 함