빈 생명주기 콜백
스프링 빈은 객체생성 => 의존관계 주입 이라는 라이프사이클을 가진다.
스프링 빈의 이벤트 라이프사이클
스프링 컨테이너 생성 => 스프링 빈 생성 => 의존관계 주입 => 초기화 콜백 => 사용 => 소멸전 콜백 => 스프링 종료
초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
소멸전 콜백: 빈이 소멸되기 직전에 호출
스프링 빈 생명주기 콜백 지원 방법 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이 필요한경우 언제든지 사용할 수 있다.
'SPRING' 카테고리의 다른 글
김영한 - 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 1일차 (0) | 2021.12.27 |
---|---|
김영한 SPRING 기본편 7일차 (0) | 2021.12.14 |
김영한 SPRING 기본편 5일차 (0) | 2021.12.13 |
김영한 SPRING 기본편 4일차 (0) | 2021.12.10 |
김영한 SPRING 기본편 3일차 (0) | 2021.12.09 |