번역 그대로 빈이 존재할 수 있는 범위
싱글톤 : 기본 스코프, 스프링 컨테이너의 시작과 종료까지 유지, 가장 넓은 스코프
프로토 타입 : 스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입까지만 관여하고 이후는 관리하지 않음, 짧은 범위의 스코프
request : 웹 요청이 들어오고 나갈때 까지 유지되는 스코프
session : 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프
application : 웹의 서블릿 컨텍스와 같은 범위로 유지되는 스코프
websocket : 웹 소켓과 동일한 생명주기를 가지는 스코프
프로토타입 스코프를 스프링 컨테이너에 조회하면 새로운 인스턴스를 생성하고 필요한 의존관계를 주입하여 반환한다.
반환이후 스프링 컨테이너는 인스턴스를 관리하지 않아서 @PreDestory 같은 종료 메서드가 호출 되지 않는다
프로토타입 빈은 프로토타입 빈을 조회한 클라이언트가 관리해야한다.
싱글톤 빈 내부에서 프로토타입 빈을 멤버 변수로 사용하면 프로토타입 빈이 당연히도 한번만 생성된다
여러 빈에서 프로토타입 빈을 주입 받으면 각각 한번씩만 생성된다.
필요할때마다 ac.getBean()으로 새로 생성하도록 한다면 의존관계를 직접 찾는 DL 의존관계조회가 되고
스프링 컨테이너에 종속적인 코드가 되고 단위테스트도 어려워진다.
ObjectProvider 는 지정한 빈을 컨테이너에서 대신 찾아주는 DL 서비스를 제공해준다.
스프링이 제공하는 기능이긴 하지만 기능이 단순해서 단위테스트를 만들거나 mock코드를 만들기는 훨씬 쉬워진다.
자바 표준을 사용하여 위 문제 해결하는 방법이다.
다만 라이브러리를 gradle에 추가해줘야한다.
스프링이 제공하는 기능과 자바 표준 기능이 겹치는 경우가 있는데 스프링이 더 다양하고 편리한 기능을 제공해주기 때문에 특별히 다른 컨테이너를 사용할 일이 없다면 스프링이 제공하는 기능을 사용하면 된다.
위의 라이브러리를 추가하면 스프링 부트는 내장 톰켓 서버를 활용해서 웹 서버와 스프링을 함께 실행시킨다.
main/resources/application.properties 에서
server.port=8080 을 변경해주면됨
request scope는 http 요청 단위로 생성되기 때문에 데이터는 섞이지않는다.
request scope를 사용하지 않고 파라미터로 서비스 계층에 데이터를 넘기면 코드가 지저분해진다
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
request 스코프 빈을 멤버 변수로 사용하는 빈이 있으면 의존성 주입에 실패한다
request 스코프의 범위는 http요청 동안이기 때문에 처음 스프링 컨테이너가 빈에 등록하고 의존성을 주입할때는 request 스코프의 범위가 아니기 때문이다
proxyMode를 설정해주면 의존성 주입할때 가짜 프록시 빈을 넣어주고 이후 빈이 사용될때 진짜 빈을 넣어준다.
provider를 사용하든 프록시를 사용하던 핵심 아이디어는 진짜 객체 조회를 꼭 필요한 시점까지 지연처리 한다는 점
어노테이션 설정 변경만으로 원복 객체를 프록시 객체로 대체할수 있는 것은 다형성과 DI 컨테이너가 가진 큰 강점이다.
클래스에는 ScopedProxyMode.TARGET_CLASS
인터페이스에는 ScopedProxyMode.INTERFACE 를 사용한다
스코프는 최소한으로 사용해야한다
스코프를 남발하면 유지보수가 어려워 질 수 있따