본문 바로가기
Programming/Spring

Bean 라이프 사이클과 범위

by TinKerBellBass 2017. 8. 19.
728x90
반응형

참고도서

초보 웹 개발자를 위한 스프링4 프로그래밍 입문
국내도서
저자 : 최범균
출판 : 가메출판사 2015.03.02
상세보기



1. bean 객체의 라이프 사이클

(1) 스프링 컨테이너의 초기화와 종료

1
2
3
4
5
6
7
8
9
10
11
12
// 1. 컨테이너 초기화
// 빈 객체의 생성과 의존 객체 주입 및 초기화
GenericXmlApplicationContext ctx = 
    new GenericXmlApplicationContext("classpath:applicationContext.xml");
 
// 2. 컨테이너 사용
// getBean() 등의 메소드를 사용해서 컨테이너에 보관된 빈 객체를 가져온다
Greeter g = ctx.getBean("greeter",Greeter.class);
 
// 3. 컨테이너 종료
// 빈 객체의 소멸
ctx.close();
cs


GenericXmlApplicationContext 의 생성자를 통해서 설정파일을 로딩하고, GenericXmlApplicationContext 객체를 생성한다. 

이 때 설정파일을 통해 스프링 컨테이너의 초기화가 일어난다.

그리고 생성된 빈 객체를 가져와 사용하면 된다.

사용이 끝난 컨테이너는 close( ) 메소드를 통해 종료 시킨다.

컨테이너가 종료되면서 빈 객체도 소멸한다.

close( ) 메소드는 AbstractApplicationContext 클래스에 정의되고

XML 기반 설정에 사용하는 GenericXmlApplicationContext 클래스, 

자바 기반 설정에 사용하는 AnnotationConfigApplicationContext 클래스는 AbstractApplicationContext를 상속하고 있기 때문에,

GenericXmlApplicationContext, AnnotationConfigApplicationContext 모두 close( ) 메소드를 사용할 수 있다.


(2) 빈 객체의 라이프 사이클


스프링 컨테이너가 관리하는 빈 객체의 라이프 사이클

① 객체생성 -> ② 의존설정 -> ③초기화 -> ④ 소멸 의 순이다.


스프링 컨테이너가 초기화 될 때, 스프링 컨테이너는 가장 먼저 빈 객체를 생성하고,

<property> <constructor-arg> 태그로 지정한 의존을 설정한다. 이 때 자동 주입을 통한 의존 설정도 수행된다.

모든 의존 설정이 완료되면, 스프링은 빈 객체가 지정한 메소드를 호출해서 빈 객체의 초기화를 수행한다.

그리고 스프링 컨테이너를 종료하면, 스프링 컨테이너는 빈 객체가 지정한 메소드를 호출해서 빈 객체의 소멸을 처리한다.


빈 객체를 초기화하고 소멸하기 위한 메소드를 사용하기 위해서, 

빈 객체는 스프링의 InitializingBean, DisposableBean 인터페이스를 구현해야 한다.


1
2
3
4
5
6
7
8
9
// 초기화에 사용되는 인터페이스와 메소드
public interface InitializingBean{
    void afterPropertiesSet() throws Exception;
}
 
// 소멸에 사용되는 인터페이스와 메소드
public interface DisposableBean{
    void destroy() throws Exception;
}
cs

 

초기화 과정이 필요한 빈 객체는 InitializingBean 인터페이스를 구현해서 afterPropertiesSet( ) 메소드를 적절히 작성하면 되고,

소멸 과정이 필요한 빈 객체는 DisposableBean 인터페이스를 구현해서 destroy( ) 메소드를 적절히 작성하면 되는 것이다.

데이터베이스 커넥션 풀을 위한 빈 객체가 있다면 초기화 과정에서 데이터베이스와 연결을 생성하고,

소멸 과정에서 데이터베이스와 연결을 끊어주면 된다.


(3) 인터페이스 구현을 통한 초기화, 소멸 설정


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!-- XML 설정 파일 -->
<bean id="client" class="spring.Client">
    <property name="host" value="서버"/>
</bean>
 
 
// 빈 객체 생성 클래스
package spring;
 
public class Client implements InitializingBean, DisposableBean{
 
    private String host;
 
    public void setHost(String host){
        this.host = host;
    }
 
    @Override
    public void afterPropertiesSet() throws Exception{
    }
 
    @Override
    public void destroy() throws Exception{
    }
}
cs


실행순서

① <property> 의존 설정, setHost( ) 메소드 호출 

② 빈 객체 초기화, afterPropertiesSet( ) 메소드 호출

③ 스프링 컨테이너를 구동시키고 빈 객체를 가져와서 사용하고, close( )로 스프링 컨테이너 종료

④ 빈 객체 소멸, destroy( ) 메소드 호출


그리고 close( ) 로 스프링 컨테이너를 종료시키지 않으면, destroy( ) 메소드는 호출되지 않는다.


(4) XML 설정과 자바 설정을 통한 초기화, 소멸 설정


외부에서 제공하는 클래스를 스프링 빈 객체로 설정해서 사용할 때는

인터페이스 상속을 통한 초기화, 소멸 과정을 설정할 수 없다.

이럴 때는 XML 설정이나 자바 설정을 통해서 초기화, 소멸 과정을 설정할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!-- XML 기반 설정을 사용하는 경우 -->
<!-- init-method 속성은 초기화 과정의 메소드를 호출 -->
<!-- destroy-method 속성은 소멸 과정의 메소드를 호출 -->
<bean id="client" class="spring.Client" 
    init-method="connect" destroy-method="close">
    <property name="host" value="서버"/>
</bean>
 
 
// 자바 설정을 사용하는 경우
 
// @Bean 의 속성으로 설정
@Configuration
public class JavaCongif{
    // 초기화 과정 - initMethod 속성, 소멸 과정 - destroyMethod 속성
    @Bean(initMethod="connect", destroyMethod="close")
    public Client client(){
        Client client = new Client();
        client.setHost("서버");
        return client;    
    }
}
 
// 초기화 과정에 사용할 메소드를 직접 @Bean 적용 메소드에서 직접 호출
@Configuration
public class JavaCongif{
    
    @Bean(destroyMethod="close")
    public Client client(){
        Client client = new Client();
        client.setHost("서버");
        client.connect();
        return client;    
    }
}
 
 
// 빈 객체 생성 클래스
package spring;
 
public class Client{
 
    private String host;
 
    public void setHost(String host){
        this.host = host;
    }
 
    // 초기화 과정에 사용해야 하는 메소드
    public void connect() throws Exception{
    }
    
    // 소멸 과정에 사용해야 하는 메소드
    public void close() throws Exception{
    }
}
cs


실행순서

① 의존 설정, setHost( ) 메소드 호출 

② 빈 객체 초기화, connect( ) 메소드 호출

③ 스프링 컨테이너를 구동시키고 빈 객체를 가져와서 사용하고, close( )로 스프링 컨테이너 종료

④ 빈 객체 소멸, close( ) 메소드 호출


인터페이스로 구현했을 때와 마찬가지로 close( ) 로 스프링 컨테이너를 종료시키지 않으면, destroy( ) 메소드는 호출되지 않는다.


2. 객체 범위

기본적으로 스프링 컨테이너에서 생성되는 빈 객체는 싱글톤의 범위를 갖는다.
사용할 빈 객체를 얻어올 때 늘 같은 객체가 반환되는 것이다.
만약 빈 객체를 얻어올 때마다 새로운 객체를 생성하게 해서 반환하게 하고 싶다면(프로토타입 범위),
XML 기반 설정의 경우 scope 속성을, 자바 기반 설정의 경우 @Scope 어노테이션을 사용해서 설정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 기본적으로 싱글톤 범위, client1 == client2 -> true
Client client1 = ctx.getBean("client", Client.class);
Client client2 = ctx.getBean("client", Client.class);
 
 
// 프로토타입으로 설정, 매번 새로운 객체 생성, 자바 기반 설정
@Bean
@Scope("prototype")
public Client client{
    Client client = new Client();
    return client;
}
 
 
<!-- 프로토타입으로 설정, 매번 새로운 객체 생성, XML 기반 설정 -->
<bean id="client" class="spring.Client" scope="prototype"/>
cs

주의해야 할 점은, 스프링 컨테이너는 프로토타입의 빈 객체를 생성하고 프로퍼티를 설정하고 초기화 작업을 수행하지만,
프로토타입 빈 객체의 소멸 메소드는 실행하지 않는다.
그렇기 때문에, 프로토타입 범위의 빈 객체를 사용할 때는 빈 객체의 소멸 처리를 직접 코드에서 직접 해야 한다.


728x90
반응형

'Programming > Spring' 카테고리의 다른 글

파일 업로드 / 예외처리  (0) 2017.08.20
AOP 기초  (0) 2017.08.19
자바 코드를 이용한 설정  (0) 2017.08.19
의존 자동 주입  (0) 2017.08.18
Spring DI  (0) 2017.08.18

댓글