스프링 빈의 라이프사이클

  • 객체 생성 ➔ 의존관계 주입 ➔ 초기화 ➔ 사용 ➔ 소멸

스프링은 의존관계 주입이 완료되면 스프링 빈에 콜백 메서드를 통해 초기화 시점을 알려준다.

 

- 생성자 : 파라미터받고, 메모리 할당, 객체 생성

- 초기화  생성된 값을 활용해서 외부 커넥션을 연결하는 무거운 동작 수행

 

이렇게 구분해서 역할을 명확하게 해야 한다.


스프링의 빈 생명주기 콜백 방법

 

1. 인터페이스 InitiallizingBean,DisposableBean

- 연결될 때, 해제할 때 알려주는 인터페이스

- InitializingBean의 afterPropertiesSet은 스프링이 해당 빈의 모든 의존성 주입(주로 setter/field 주입)을 마친 후에 호출

   단점

    - 스프링 전용이라 의존적이다.

    - 초기화, 소멸메서드 이름 변경이 안된다.

    - 외부 라이브러리에 적용 못함.

 

2. 설정 정보에 초기화 메서드, 종료 메서드 지정

- 메서드 이름 자유롭다.

- 외부 라이브러리에도 적용됨.

+) 종료 메서드 추론

  - 종료 메서드 close, shutdown이 있으면 자동으로 종료 메서드로 불려진다.

 

3. 애노테이션 @PostConstruct, @PreDestroy

- 걍 이 방법 쓰면 됩니다!

- 스프링이 아니라 자바 표준이라 다른 컨테이너에서도 작동함.

- 외부 라이브러리에는 적용하지 못함. 

 

 


 

빈 스코프의 종류

- 싱글톤 : 디폴트! 스프링 컨테이너 시작과 끝날때 까지 가장 길다.

- 프로토타입 : 스프링이 생성 + 의존관계 주압까지만 관여하고 던져버린다. 난 몰라 시전

- 웹 관련

      1) request : 주로 사용. 웹 요청이 들어오고 나갈 때까지 유지.

      2) session : 웹 세션 생성-종료까지 유지

      3) application : 웹의 서블릿 컨텍스트와 같은 범위

 

 


프로토타입 스코프 

- 프로토타입 빈은 객체 생성 후 던지고 관리 안함.

- 이후 또 요청이 있으면 또 객체 만든다.

- 만약 종료 메서드가 필요하다면 클라이언트가 해야함.

 

싱글톤 빈은 스프링 컨테이너 생성 시점에 초기화 메서드 실행, 컨테이너 종료될 때 닫기

프로토타입 빈은 조회할 때 초기화 메서드 실행 , 수동으로 닫기

 

 

프로토타입 빈을 싱글톤 빈과 함께 사용시 문제점

- 싱글톤 빈이 프로토타입 빈을 상요할 때 싱글톤은 생성 시점에만 의존관계를 주입받아서

  사용할 때마다 프로토타입 빈을 생성하고 싶으면 아래처럼 해결해야 함.

 

DL (Dependency Lookup)

- 의존관계를 외부에서 주입받는게 아니라 직접 필요한 의존관계를 찾는 것.

 

스프링 제공 ObjectFactory, ObjectProvider

- 내부의 getObject() 를 호출

- 스프링에서만 쓸 수 있음.

@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
	PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
	prototypeBean.addCount();
	int count = prototypeBean.getCount();
	return count;
}

 

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

 

 

자바 표준 Provider.get()

- 라이브러리 끌어와야 함. 대신 심플함.

- 스프링말고 다른 컨테이너 사용 가능함.

 


웹 스코프

- 종료시점까지 스프링이 관리 해줌.

- request: 1개의 HTTP요청 마다 객체 생성함.

- 근데 http 요청 안온 상태에서 빈을 띄우려고 하니까 오류가 남.

이럴 때, ObjectProvider를 사용하면 된다!


 

스코프와 프록시

- 진짜가 아닌 가짜 프록시를 만들어 주입해준다.

- CGLIB이라는 라이브러리 활용

- 빈에는 가짜 프록시를 등록한다.

- 진짜 요청이 왔을 때 가짜 프록시에서 진짜 빈 요청을 위임하는 로직이 들어있다.

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyLogger {
}

 

proxyMode로는 TARGET_CLASS , INTERFACE가 있다.

 

 

핵심은 진짜 객체 조회를 할때까지 지연처리한다는 점이 중요한 것임.

 

 

- Proxy 방식을 사용하면 싱글톤 빈은 마치 일반 빈을 사용하는 것처럼 편리하게 Request 스코프 빈의 메서드를 호출할 수 있다.

   Provider처럼 getObject()를 명시적으로 호출할 필요가 없어 코드가 간결해짐.

 

+ Recent posts