본문 바로가기

SPRING

김영한 SPRING 기본편 6일차

빈 생명주기 콜백

 

스프링 빈은 객체생성 => 의존관계 주입 이라는 라이프사이클을 가진다.

 

스프링 빈의 이벤트 라이프사이클

 

스프링 컨테이너 생성 => 스프링 빈 생성 => 의존관계 주입 => 초기화 콜백 => 사용 => 소멸전 콜백 => 스프링 종료

 

초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출

소멸전 콜백: 빈이 소멸되기 직전에 호출

 

스프링 빈 생명주기 콜백 지원 방법 3가지

 

1. 인터페이스(InitializingBean, DisposableBean)

 

 

InitializingBeand 은 afterPropertiesSet() 메소드로 초기화를 지원한다.

DisposableBean 은 destroy() 메소드로 소멸을 지원한다.

 

단점

 

이 인터페이스는 스프링 전용 인터페이스라 코드가 스프링 전용 인터페이스에  의존한다.

초기화, 소멸 메소드의 이름을 변경할 수 없다.

외부라이브러리에 적용할 수 없다.

 

빈 등록 초기화, 소멸 메소드 지정

 

 

특징

 

메소드 이름을 자유롭게 줄 수 있다.

스프링 빈이 스프링 코드에 의존하지 않는다.

외부라이브러리에도 초기화,종료 메소드를 적용할 수 있다.

 

종료 메소드 추론

 

@Bean의 destroyMethod 속성에는 기본값이 (inferred)(추론)으로 등록되어 있다.

이 추론 기능은 close, shutdown 라는 이름의 메소드를 자동으로 호출해준다.

이 기능은 종료 메소드를 추론해서 호출 해준다
(대부분 라이브러리는 close, shutdown 으로 종료메소드를 사용하기 때문)

추론기능을 사용하지 않을 때는 destroyMethod="" 로 공백을 지정하면 된다.

 

애노테이션 @PostConstruct , @PreDestroy

 

특징

 

최근 스프링에서 권장하는 방법.

패키지가 스프링에 종속적인 기술이 아니라 다른 컨테이너에서도 동작한다.

유일한 단점으로 외부라이브러리에는 적용하지 못한다. 외부라이브러리는 @Bean 기능을 사용!

 

빈 스코프 

 

스코프는 빈이 존재할 수 있는 범위를 뜻한다.

 

스코프 종류

 

싱글톤: 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프이다.

프로토타입:프로토타입 빈의 생성과 의존관계 주입까지만 관여하고 더는 관리하지않는 스코프이다.

웹 관련 스코프: 

request : 웹 요청이 들어오고 나갈때까지 유지되는 스코프

session : 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프

application : 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프

 

프로토타입 스코프

 

스프링 컨테이너는 프로토타입 빈을 생성하고, 의존관계 주입, 초기화까지만 처리한다.

프로토타입 빈을 관리할 책임은 프로토타입 빈을 받은 클라이언트에 있다.

@PreDestroy 같은 종료메소드가 호출 되지 않는다.

 

싱글톤 빈은 스프링 컨테이너 생성 시점에 초기화 메소드가 실행 된다.

 

 

그러나 프로토타입 빈은 스프링 컨테이너에서 빈을 조회할 때 생성되고, 초기화 메소드도 실행된다.

프로토타입 빈을 2번 조회 해서 초기화도 2번 실행됐다.

프로토타입 빈은 @PreDestroy 같은 종료메소드가 실행되지않은 것을 볼 수 있다.

 

 

 

특징

 

스프링 컨테이너에 요청할 때 마다 새로 생성된다.

프로토타입 빈의 생성과 의존관계 주입 , 초기화 까지만 관여한다.

종료 메소드가 호출되지 않는다.

 

프로토타입 스코프 - 싱글톤 빈과 함께 사용시 Provider로 문제 해결

 

싱글톤 빈과 프로토타입 빈을 함께 사용할 때 항상 새로운 프로토타입 빈을 생성하려면

싱글톤 빈이 프로토타입을 사용할 때 마다 스프링 컨테이너에 새로 요청하는 것이다.

 

 

ac.getBean()을 통해서 항상 새로운 프로토타입 빈이 생성된다.

의존관계를 외부에서 주입받는게 아니라 이렇게 직접 필요한 의존관계를 찾는 것을 Dependency Lookup (DL) 의존관계 조회라 한다.

 

ObjectProvider

 

 

prototypeBeanProvider.getObject() 을 통해서 항상 새로운 프로토타입 빈이 생성된다.

getObject() 를 호출하면 내부에서 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다.(DL)

 

JSR-330 Provider

 

javax.inject.Provider 라는 JSR-330 자바 표준을 사용하는 방법이다.

이 방법은 사용하려면 javax.inject:javax.inject:1 라이브러리를 gradle에 추가해야한다.

 

 

prototypeBeanProvider.get() 을 통해서 항상 새로운 프로토타입 빈이 생성된다.

get()을 호출하면 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다.(DL)

 

정리

 

프로토타입 빈은 거의 사용할일이 드물다.

싱글톤 빈으로 대부분의 문제를 해결 할 수 있다.

ObjectProvider , JSR330 Provider 등은 프로토타입 뿐만 아니라 DL이 필요한경우 언제든지 사용할 수 있다.

 

 

출처: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8