컨테이너 생명 주기 [Spring]
반응형

본 게시글은 Seoul wiz의 신입SW인력을 위한 실전 자바(Java) 스프링(Spring)을 참고하여 작성한 글입니다.

 

컨테이너 생명 주기

스프링에서 컨테이너의 생명 주기는 다음과 같다. [생성-> 설정 -> 사용 -> 종료]

public static void main(Strig[] args){
    //스프링 컨테이너 생성
    GenericXmlApplicationContext ex = new GenericXmlApplicationContext();

    //컨테이너 설정
    ex.load("classpath:XML경로");
    ex.refresh();

    //컨테이너 사용
    Example example = ex.getBean("Example",Example.class);
    /*사용하기
    .
    .
    .*/

    //컨테이너 종료
    ex.close
}

 

초기화, 소멸 메소드 정의

우선 가장 기본적인 초기화 메소드의 구현은 다음과 같다.

InitializingBean (interface) 구현 -> afterPropertiesSet() 메소드 overrride하기

이렇게 하면 Bean 생성시 초기화 과정에서 호출하게 된다.

ctx.refresh() //이때 실행됨

 

소멸시 실행되는 메소드는

DisposableBean (interface) 구현 -> destroy() 메소드 override를 함으로써 정의할 수 있다.

Bean 소멸 과정에서 호출된다.

ctx.destroy() //이때 실행됨 (컨테이너 소멸 단계, 컨테이너 소멸시 빈 자동 소멸)

 

이때 메소드 자체를 정의해서 하는 방법도 있다.

@PostConstruct (빈 초기화 과정에서 호출) 초기화 과정에서 실행할 함수 정의 후 메소드 주석으로 명시하면 된다.

@PostConstruct
public void InitBean(){
    //빈 초기화시 실행
}

마찬가지로 @PreDestroy 빈 소멸시 실행할 함수 정의 후 메소드 주석으로 명시하면 된다.

@PreDestroy
public void DestroyBean(){
    //빈 소멸시 실행
}

 

스프링 빈 범위

스프링 빈 생성시 scope을 가지고 있다. Scope (범위)는 어디까지 객체가 영향을 미치는지 결정

<bean id ="scopetest" class="xxx.클래스파일.." scope = "prototype"></bean>

xml 파일에서는 위와 같이 설정할 수 있는데, 이때 default 는 singleton이다.

Java에서는 annotation으로 @Scope("singleton")과 같이 설정할 수 있다.

대략적인 Scope의 종류는 다음과 같다. Singleton과 Prototype을 제외한 3가지는 HTTP 통신에서 사용된다. 

Scope 설명
singleton 하나의 Bean 정의에 단 하나의 객체만 존재
prototype 하나의 Bean 정의에 다수의 객체
request 하나의 Bean 정의에 대해 하나의 HTTP request 생명주기 안에 하나만 존재
session 하나의 Bean 정의에 대해 하나의 HTTP session 생명주기 안에 하나만 존재
global session 하나의 Bean 정의에 대해 하나의 global HTTP session 생명주기 안에 하나만 존재

여기서 singleton은 객체를 한 개만 사용하겠다는 뜻으로, 여러 객체를 만들어도 같은 객체를 가르키게 된다.

prototype은 객체를 여러개 사용한다는 뜻으로, 모든 요청에서 새로운 객체를 생성하게 됨.

 

보통 상태가 없는 공유 객체, 읽기용, 반드시 공유가 필요한 상태를 지닌 객체의 경우 싱글톤 (ex) DB)

쓰기가 많아 동기화 비용이 생성보다 큰 경우에는 비싱글톤으로 한다고 한다.

 

여담으로 싱글톤 패턴은 아예 디자인 패턴으로도 정의되어 있을 만큼 매우매우 중요한 부분이다.

자바에서 간단하게 다음과 같이 구현할 수 있다.

class DatabaseConnection {
	
	private static DatabaseConnection instance = null;
	private static int count = 0;
	
	private DatabaseConnection() {
		System.out.println("DatabaseConncetion Constructor");
	}
	//무조건 하나만 존재하게
	public synchronized static DatabaseConnection instance() {
		if(instance == null) {
			instance = new DatabaseConnection();
			count++;
		}
		return instance;
	}
}

 

반응형