[Java]빈 스코프

전재준·2022년 1월 24일
0

Java

목록 보기
15/15

스프링의 빈스코프는 다음과 같은 스코프를 지원한다.

  • 싱글톤: 기본 스코프, 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프이다.
  • 프로토타입: 스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는 매우 짧은 범위의 스코프이다.
  • request: 웹 요청이 들어오고 나갈때 까지 유지되는 스코프이다.
  • session: 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프이다.
  • application: 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프이다.

전 게시물에서 싱글톤에 대해 알아봤으니 다른 스코프 프로토타입에 대해 알아보자.

prototype scope

프로토 타입은 빈을 생성하고, 의존관계 주입, 초기화까지만 처리를 한다. 빈 생명주기의 콜백에서 @PostConstruct, @PreDestroy로 생명주기를 제어할 수있지만, 프로토 타입은 @PreDestroy 같은 종료 메서드가 호출되지 않는다.

프로토타입 빈의 특징

  • 스프링 컨테이너에 요청할 때 마다 새로 생성된다.
  • 스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입 그리고 초기화까지만 관여한다.
  • 종료 메서드가 호출되지 않는다.
  • 그래서 프로토타입 빈은 프로토타입 빈을 조회한 클라이언트가 관리해야 한다. 종료 메서드에 대한 호출도
    클라이언트가 직접 해야한다.

싱글톤 빈과 함께 사용시 문제점

스프링은 일반적으로 싱글톤 빈을 사용하므로, 싱글톤 빈이 프로토타입 빈을 사용하게 된다. 그런데 싱글톤 빈은 생성 시점에만 의존관계를 주입 받기 때문에, 프로토타입 빈이 새로 생성되기는 하지만, 싱글톤 빈과 함께 계속 유지되는것 이다.

prototypeBean 은 이미 과거에 주입이 끝난 빈이므로, 주입시점에 스프링 컨테이너에 요정해서 프로토타입빈이 새로 생성된것이지, 사용 할 때 마다 새로 생성되지 않는다.

싱글톤 빈과 함께 사용시 Provider로 문제 해결

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

provider의 get()을 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다. 필요할 때만 DL의 기능을 통해 호출해서 사용.


request 특징

HTTP 요청 하나가 들어오고 나갈 때 까지 유지되는 스코프, 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고, 관리된다.

사용자의 요청이 들어 올 때 마다 로그를 쌓는 request스코프의 class를 만들어보자.

컨트롤러에서 의존성을 주입받아 해당 MyLogger에 로그 쌓는 기능을 사용해보자.

하지만 스프링 기동시 Error creating bean with name 'myLogger': Scope 'request' is not active for the current thread.... 라는 오류가 발생.

그이유는 request 스코프 빈은 사용자의 요청이 들어와야 생성되므로 주입이 불가능하다.

스코프와 Provider 해결법

위에 사용했던 것처럼 Provider를 통해 호출하는 시점까지 request scope 빈의 생성을 지연할 수 있다.

스코프와 프록시 해결법

이번에는 프록시 방법을 사용해 보자

  • 적용 대상이 인터페이스가 아닌 클래스면 TARGET_CLASS 를 선택
  • INTERFACES

이렇게 하면 MyLogger의 가짜 프록시 클래스를 만들어두고 HTTP request와 상관없이 가짜 프록시 클래스를 다른 빈에 미리 주입해 둘 수 있다.

CGLIB라는 라이브러리로 내 클래스를 상속 받은 가짜 프록시 객체를 만들어서 주입한다.

정리

  • 프록시 객체 덕분에 클라이언트는 마치 싱글톤 빈을 사용하듯이 편리하게 request scope를 사용할 수 있다.
  • 사실 Provider를 사용하든, 프록시를 사용하든 핵심 아이디어는 진짜 객체 조회를 꼭 필요한 시점까지 지연처리 한다는 점이다.
  • 단지 애노테이션 설정 변경만으로 원본 객체를 프록시 객체로 대체할 수 있다. 이것이 바로 다형성과 DI 컨테이너가 가진 큰 강점이다.
  • 꼭 웹 스코프가 아니어도 프록시는 사용할 수 있다.
  • 마치 싱글톤을 사용하는 것 같지만 다르게 동작하기 때문에 결국 주의해서 사용해야 한다.
  • 이런 특별한 scope는 꼭 필요한 곳에만 최소화해서 사용하자, 무분별하게 사용하면 유지보수하기 어려워진다.

참고자료

0개의 댓글

관련 채용 정보