You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
provider.get()을 통해서 항상 새로운 프로토타입 빈이 생성되는 것을 확인할 수 있음
provider의 get()을 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환 (DL)
자바 표준이고, 기능이 단순하므로 단위테스트를 만들거나 mock 코드를 만들기는 훨씬 쉬워짐
딱 필요한 DL 정도의 기능만 제공
정리
웹 애플리케이션을 개발해보면, 싱글톤 빈으로 대부분의 문제를 해결할 수 있기 때문에 프로토타입 빈을 직접적으로 사용하는 일은 매우 드물다. ObjectProvider, JSR330 Provider 등은 프로토타입뿐만 아니라 DL이 필요한 경우는 언제든지 사용할 수 있다.
💡 참고 자바 표준 JSR-330 Provider vs ObjectProvider
ObjectProvider은 별도의 라이브러리 추가 없이 편리하게 사용할 수 있음
(그럴일은 거의 없지만) 코드를 스프링이 아닌 다른 컨테이너에서도 사용할 수 있어야 한다면 자바 표준 사용
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
프로토타입 스코프 - 싱글톤 빈과 함께 사용시 문제점
프토토타입스코프의 빈 요청 ➡️ 항상 새로운 객체 인스턴스 생성해서 반환싱글톤 빈과 함께 사용할 때는 의도한 대로 잘 동작하지 않음
프로토타입 빈 직접 요청
프로토타입 빈을 직접 요청하면 할 때마다 빈을 새로 생성해서 해당 빈의 count 필드 값은 0이다. 여러번 호출해도 0이다.
싱글톤 빈에서 프로토타입 빈 사용
clientBean은 싱글톤이므로 스프링 컨테이너 생성 시점에 생성되고 의존관계 주입도 발생함clientBean은 의존관계 자동 주입을 사용함. 주입 시점에 스프링 컨테이너에 프로토타입 빈을 요청clientBean에 반환. 프로토타입 빈의 count 필드 값은 0임clinetBean은 프로토타입 빈을 내부 필드에 보관함clientBean을 스프링 컨테이너에 요청하면 싱글톤이므로 항상 같은clientBean이 반환됨clientBean.logic()을 호출clientBean은 prototypeBean의addCount()를 호출해서 프로토타입 빈의 count를 증가하여 count 값은 1이 됨clientBean.logic()호출clientBean은 prototypeBean의addCount()를 호출해서 프로토타입 빈의 count를 증가함. 원래 1이었던 값이 공유되어 2가 된다.스프링은 일반적으로 싱글톤 빈을 사용하므로 싱글톤 빈이 프로토타입 빈을 사용하게 된다. 싱글톤 빈은 생성 시점에만 의존관게 주입을 받기 때문에 프로토타입 빈이 새로 생성되기는 하지만, 싱글톤 빈과 함께 계속 유지되는 것이 문제
💡 참고 여러 빈에서 같은 프로토타입 빈을 주입 받으면, 주입 받는 시점에 각각 새로운 프로토타입 빈이 생성됨
clientA ➡️ prototypeBean@x01
clientB ➡️ prototypeBean@x02
사용할 때마다 새로 생성되는 것은 아니다.
프로토타입 스코프 - 싱글톤 빈과 함께 사용시 Provider로 문제 해결
스프링 컨테이너에 요청
ac.getBean()을 통해서 항상 새로운 프로토타입 빈이 생성됨ObjectFactory, ObjectProvider
과거에
ObjectFactory가 있었고 여기에 편의 기능이 추가된 것이ObjectProviderprototypeBeanProvider.getObject()을 통해서 항상 새로운 프로토타입 빈이 생성되는 것을 확인할 수 있음ObjectProvider의getObject()를 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환 ( DL )ObjectFactory: 기능이 단순, 별도의 라이브러리 필요 없음, 스프링에 의존ObjectProvider: ObjectFactory를 상속, 옵션/스트림 처리 등 편의 기능이 많고 별도의 라이브러리 필요 없음, 스프링에 의존JSR-330 Provider
jakarta.inject.Provider(스프링부트 3.0 이상부터) 라는 JSR-330 자바 표준을 사용하는 방법이다.provider.get()을 통해서 항상 새로운 프로토타입 빈이 생성되는 것을 확인할 수 있음provider의get()을 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환 (DL)정리
웹 애플리케이션을 개발해보면, 싱글톤 빈으로 대부분의 문제를 해결할 수 있기 때문에 프로토타입 빈을 직접적으로 사용하는 일은 매우 드물다.
ObjectProvider,JSR330 Provider등은 프로토타입뿐만 아니라 DL이 필요한 경우는 언제든지 사용할 수 있다.💡 참고
자바 표준 JSR-330 Provider vs ObjectProvider
ObjectProvider은 별도의 라이브러리 추가 없이 편리하게 사용할 수 있음웹 스코프
웹 스코프 종류
HTTP request 요청 당 각각 할당되는 request 스코프
request 스코프 예제
웹 스코프는 웹 환경에서만 동작하므로 웹 환경이 동작하도록 라이브러리를 추가해줘야 함
@Scope(value="request")를 사용해서 스코프 지정@PostConstruct초기화 메서드를 사용해서 uuid를 생성해서 저장@PreDestory를 사용해서 종료 메시지를 남김requestURL은 이 빈이 생성되는 시점에는 알 수 없으므로 외부에서 setter로 입력 받음출력을 해보면... 기대와 달리 오류 발생 !!
스프링 애플리케이션을 실행하는 시점에 싱글톤 빈은 생성해서 주입이 가능하지만, request 스코프 빈은 아직 생성되지 않음
스코프와 Provider
ObjectProvider덕분에ObjectProvider.getObject()를 호출하는 시점까지 request scope 빈의 생성 지연 (정확히 말하면 빈의 생성을 지연시킨다보다는 빈의 호출 시점을 지연하는 것임)스코프와 프록시
TARGET_CLASS선택INTERFACES선택나머지 코드는 Provider 사용 이전으로 돌림 ➡️ 정상 동작
웹 스코프와 프록시 동작 원리
CGLIB라는 라이브러리로 내 클래스를 상속 받은 가짜 프록시 객체를 만들어서 주입한다.
가짜 프록시 객체는 요청이 오면 그때 내부에서 진짜 빈을 요청하는 위임 로직이 들어있음
가짜 프록시 객체는 원본 클래스를 상속 받아서 만들어졌기 때문에 이 객체를 사용하는 클라이언트 입장에서는 사실 원본인지 아닌지도 모르게 동일하게 사용할 수 있음 (다형성)
프록시 객체 덕분에 클라이언트는 마치 싱글톤 빈을 사용하듯이 request scope를 사용할 수 있음
무엇을 사용하든 핵심 아이디어는 진짜 객체 조회를 꼭 필요한 시점까지 지연처리함
애코테이션 설정 변경만으로 원본 객체를 프록시 객체로 대체할 수 있음
웹 스코프가 아니어도 프록시는 사용할 수 있음
💡 주의
All reactions