[WIL] GDG Spring 세션 3주차

Nakyeong Lee·2024년 10월 5일
0

Bean이란 스프링 컨테이너가 관리하는 자바 객체이다. 여기서 중요한 개념 중 하나가 빈의 스코프(Scope) 인데, 빈 스코프는 빈 인스턴스가 생성되고 소멸하는 컨테이너 영역을 의미한다.

빈스코프

빈 스코프는 빈을 생성하고 소멸시키는 방법을 결정하여 메모리 관리와 빈의 생성 시점 등을 세밀하게 컨트롤한다.
스프링에서는 기본적으로 6가지의 빈 스코프가 제공된다.

scope설명
singleton하나의 빈 인스턴스만 생성하고 캐시에 저장해 재사용
prototype요청할 때마다 새로운 인스턴스를 생성
request각 HTTP 요청마다 새로운 빈을 생성
session각 HTTP 세션마다 빈을 생성하고, 세션이 끝나면 소멸
applicationServletContext 수준에서 하나의 인스턴스를 생성
websocket각 WebSocket 세션마다 별도의 빈 인스턴스를 생성

Singlton scope

단일 인스턴스를 생성해서 캐시에 저장하고, 이후 모든 요청에서 그 캐시된 인스턴스를 반환하는 방식이다. 이 방식은 메모리 절약과 성능 최적화에 도움을 준다.

Prototype scope

빈이 호출될 때마다 새로운 객체를 생성한다. 일반적으로 상태를 가진(stateful) 빈은 프로토타입 스코프를 사용하고, 상태가 없는(stateless) 빈은 싱글톤 스코프를 사용한다. 다른 스코프와 달리 프로토타입은 스프링 컨테이너가 모든 생명주기를 관리하지는 않으며, 호출에 의해 빈이 생성되면 컨테이너에서는 빈에 대한 기록을 유지하지 않는다.

Web-aware 스코프
Request, Session, Application, Websocket 스코프는 주로 웹 애플리케이션에서 사용된다. 이들은 웹 관련 요청을 처리할 때만 사용 가능하고, Spring Web MVC와 함께 사용할 때는 DispatcherServlet이 별도의 설정 없이 자동으로 처리해준다.

Request scope

모든 로그인 Http 요청마다 LoginAction 빈에 대한 새로운 인스턴스를 만들어 request를 처리한다. 각 인스턴스가 별개로 존재하기 때문에 객체 내부의 속성 값 등을 변경해도 다른 인스턴스에는 영향을 끼치지 않는다. 각 객체는 request processing 이 끝날 경우 사라진다.

Session scope

session scope 로 정의된 빈으로부터 생성된 객체는 http session 이 만료되기 전까지 메모리를 차지한다. 웹 어플리케이션 세션에 대한 데이터를 유지하고 관리할 때 사용된다.

Application scope

ServletContext 레벨에서 유일한 인스턴스를 생성한다. HTTP 요청이 들어오면 웹 서버는 요청을 처리하기 위해 새로운 스레드와 서블릿을 생성하며, 애플리케이션 스코프로 생성된 빈은 스레드마다 별도의 인스턴스가 생성되어 사용되기 때문에 멀티스레드 환경에서 안전하게 빈을 사용할 수 있다.

Websocket scope

웹소켓은 Http 와 다른 프로토콜을 사용하며, 클라이언트와 서버 간 양방향 통신을 가능케 한다. 또한 각 웹소켓 세션마다 별도의 빈 인스턴스가 생성되며 웹소켓 세션의 생명주기와 함께 관리된다. (@WebSocketScope 는 Spring 의 WebSocket 구현체인 Spring Websocket에서만 사용할 수 있다.)

빈 생명주기 콜백

Spring 컨테이너가 빈을 관리할 때 호출되는 일련의 메서드들

빈 생성 - 스프링 컨테이너가 빈을 생성
의존성 주입 - 생성된 빈에 필요한 의존성을 주입
초기화 콜백 - 초기화 작업을 할 수 있도록 특정 메서드가 호출
빈 사용 - 정상 초기화 후 애플리케이션에서 빈을 사용
소멸 콜백 - 리소스 해제나 연결 종료 등의 작업 수행

스프링의 빈 생명주기 콜백 관리

빈 생명주기 콜백 관리 방식 3가지

방식장점단점
인터페이스(InitializingBean, DisposableBean)명확한 라이프사이클 관리스프링에 의존적, 메서드 이름 변경 불가
설정 정보를 통한 메소드 등록메서드 이름 자유롭게 설정 가능, 외부 라이브러리에도 적용 가능initMethod, destroyMethod 직접 설정 필요
@PostConstruct, @PreDestroy 어노테이션가장 권장되는 방법, 자바 표준 어노테이션으로 다른 컨테이너에서도 동작외부 라이브러리에는 적용 불가

Sample Code

  1. 인터페이스
public class ExampleBean implements InitializingBean, DisposableBean {
	@Override
	public void afterPropertiesSet() throws Exception {
		// 초기화 콜백 (의존관계 주입이 끝나면 호출)
	}
	@Override
	public void destroy() throws Exception {
		// 소멸 전 콜백 (메모리 반납, 연결 종료와 같은 과정)
	}
}
  1. 설정 파일
public class ExampleBean {
	public void initialize() throws Exception {
		// 초기화 콜백 (의존관계 주입이 끝나면 호출)
	}
	public void close() throws Exception {
		// 소멸 전 콜백 (메모리 반납, 연결 종료와 같은 과정)
	}
}

@Configuration
class LifeCycleConfig {
	@Bean(initMethod = "initialize", destroyMethod = "close")
	public ExampleBean exampleBean() {
	}
}
  1. 어노테이션
public class NetworkClient{
	...
	@PostConstruct
	public void init() {
		System.out.println("NetworkClient.init");
		connect();
		call("초기화 연결 메세지");
	}
    
	@PreDestroy
	public void close() {
		System.out.println("NetworkClient.close");
		disconnect();
	}
}
profile
Web Backend Developer

0개의 댓글