우선 자바 빈은 AnnotationConfigApplicatonContext 클래스로 대표되는 스프링 컨테이너에 등록되고, 사라지는데 특정한 주기를 갖는다.
쉽게 설명하자면,
객체생성->의존설정->초기화->소멸 인데, 각 단계별로 설명하자면,
1. 객체생성: AnnotationConfigApplicationContext 의 생성자로, 자바 설정클래스가 들어갔을때, 설정클래스에 구현된 자바빈 들의 객체를 생성하고 컨테이너에 등록한다.
2.객체를 생성해서 컨테이너에 등록하는 과정에서 만약 @Autowired에 의한 자동의존 주입이 필요하다면, 기존에 등록된 자바빈 객체들중 해당 타입과 같은 빈을 주입한다.
여기까지는 앞서 포스트에서 설명했고, 우리도 다 알고 있는 내용이다. 그러나 다음 두 내용은 새로운 내요이다.
3.모든 의존설정이 완료되면, 빈 객체의 초기화를 수행한다. 빈객체를 초기화하기 위해 스프링은 빈 객체의 지정된 메서드를 호출하는데, 커스텀으로 사용자가 직접 @Bean의 값으로 정해주거나, 애초에 등록하려는 클래스에 표준 인터페이스를 상속시켜서, 구해주는 방법이 있다.
*여기서 지정된 메서드란, InitializingBean 인터페이스에 구현된 추상메서드인 afterPropertiesSet().-> 초기화 메서드
DisposableBean 인터페이스에 구현된 추상메서드인 destroy()->소멸 메서드이다.
책에서는 우리가 자바빈을 등록하는 클래스가 이 두 인터페이스를 상속받아 구현하면, 스프링이 알아서 빈 사이클 주기를 돌때, 초기화 할때는 afterProperitiesSet()을 호출하고, 소멸시킬때는 destroy() 메서드를 호출시켜 준다고 한다.
이전까지 내가 한 실습에서 난 한번도 설정클래스 @Configuration이나(수동설정), 자동 자바빈 등록을 위한 @Component가 붙은 클래스에서 위 두 인터페이스를 구현 한 적이 없다. 그래서 나는 초기화나 소멸의 단계를 눈으로 확인해 보지도 못했고, 생소하게 느낀거 같다.
표준 인터페이스를 구현받아서, 빈 초기화, 소멸 주기를 진행할수 있는 코드.
public class Client implements InitializingBean, DisposableBean {
private String host;
public void setHost(String host) {
this.host = host;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Client.afterPropertiesSet() 실행");
}
public void send() {
System.out.println("Client.send() to " + host);
}
@Override
public void destroy() throws Exception {
System.out.println("Client.destroy() 실행");
}
}
이 클래스를 @Configuration에 등록 한 뒤, Main 클래스를 실행 하면, afterPropertiesSet(), destroy() 함수를 별도로 호출하지 않았는데도, 빈 라이프사이클 주기에 맞추어
콘솔창에
"Client.afterPropertiesSet() 실행", "Client.destroy() 실행" 등이 나타남을 볼 수 있다.
아래의 코드는 커스텀 메서드로 사용자가 직접 어떤 메서드를 초기화 시 실행할껀지, 소멸 단계에서 실행할껀지 정할 수 있다.
@Configuration
public class AppCtx {
@Bean
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
@Bean(initMethod = "connect", destroyMethod = "close")
public Client2 client2() {
Client2 client = new Client2();
client.setHost("host");
return client;
}
}
그리고 또 난 옛 포스트에서 한번, 자바 빈을 생성해서 컨테이너에 등록할때는 만일 "빈 의 식별자가 동일하다면 한개의 객체만을 생성해서 컨테이너에 등록한다." 라고 했다. 즉, 싱글톤 객체인 것이다.
하지만 여기서 @Scope("prototype") 이런 애너테이션을 붙이면, 싱글톤이 아니라 빈 객체를 getBean 메서드를 통해서 구할 때마다, 매번 새로운 객체를 생성한다.
@Configuration
public class AppCtxWithPrototype {
@Bean
@Scope("prototype")
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
@Bean(initMethod = "connect", destroyMethod = "close")
@Scope("singleton")
public Client2 client2() {
Client2 client = new Client2();
client.setHost("host");
return client;
}
}
page 150 공부 완료.
공부시간: 3시간, 순공부/ 프로그래밍 시간:1시간.
Input 이 없으면 Output이 절대 없다. 시간을 쏟아붇자.
'기록 > Spring framework' 카테고리의 다른 글
스프링 AOP의 기본 개념: Advice, joinpoint,Pointcut,Aspect 2021-06-07 (0) | 2021.06.08 |
---|---|
프록시와 AOP 프로그래밍 [최범균 스프링 5] 2021-06-04 (2) | 2021.06.05 |
빈 객체 등록의 자동화: 컴포넌트 스캔( @Autowired 과는 별개의 개념임. 혼동X) 2021-06-02 (0) | 2021.06.02 |
자동의존의 대상이 되는 클래스가 자손클래스일때, @Autowired 사용시 에러 처리법. 2021-06-01 (0) | 2021.06.01 |
스프링 의존 자동 주입 @Autowired와 @Qualifier, 2021-05-31 (0) | 2021.06.01 |