[spring] bean Scopes 빈 객체 범위 정의
by mini_min[spring] bean Scopes 빈 객체 범위 정의
✔️ 스프링 빈 스코프
: Bean 정의를 통해 객체의 종속성, 설정 값을 줄 수 있을 뿐만 아니라 객체의 범위도 정의할 수 있다.
기본적으로 스프링은 모든 Bean 을 singleton 으로 생성 및 관리한다.
📓 스프링 프레임워크 6가지 scope
- singleton : 스프링 컨테이너에 한 개의 빈 인스턴스만 생성 (기본)
- prototype : 스프링 컨테이너에 빈을 요청할 때 마다 새로운 빈 인스턴스 생성
- request : HTTP 요청 마다 빈 객체 생성 (WebApplicationContext 에서만 적용)
- session : HTTP 세션 마다 빈 객체 생성 (WebApplicationContext 에서만 적용)
- application : 웹 응용 프로그램에 대하여 하나의 객체만 생성 (WebApplicationContext 에서만 적용)
- websocket : 전체 수명주기 동안 단일 인스턴스가 생성
✔️ Bean Scope 설정
: <bean> 태그의 scope 속성을 이용해서 빈의 범위를 설정한다.
scope = 빈범위
-- 예시
-- applicationContext.xml
<!-- scope : 기본 - singleton : 하나의 객체만 생성한다. -->
<bean id="movie" class="com.scope1.Movie" />
<!-- prototype : 빈에서 객체를 호출할 때 마다 객체가 생성된다. -->
<bean id="music" class="com.scope1.Music" scope="prototype"/>
-- 자바 App 실행 파일
✨ prototype 은 컨테이너에서 빈을 가져올 때마다 객체 생성하여 다운 캐스팅해준다.
✨ 기본 singleton 의 경우 다운 캐스팅할 필요가 없다.
public static void main(String[] args) {
AbstractApplicationContext context =
new GenericXmlApplicationContext("classpath:com/scope1/applicationContext.xml");
try {
// 다운 캐스팅 할 필요가 없다.
Movie movie1 = context.getBean(Movie.class);
Movie movie2 = context.getBean(Movie.class);
// 기본 : singleton
if(movie1== movie2) {
System.out.println("movie : 동일한 객체 ");
} else {
System.out.println("movie : 다른 객체");
}
movie1.play();
movie2.play();
System.out.println("----------------------");
//prototype : 컨테이너에서 빈을 가져올 때마다 객체 생성한다.
Music music1 = (Music)context.getBean("music");
Music music2 = (Music)context.getBean("music");
if(music1== music2) {
System.out.println("music : 동일한 객체 ");
} else {
System.out.println("music : 다른 객체");
}
music1.play();
music2.play();
System.out.println("----------------------");
} finally {
context.close();
}
}
✔️ <aop:scoped-proxy/>
: 생명주기가 더 짧은 bean 을 생명주기가 더 긴 bean 에 주입하면 문제가 생긴다.
이러한 문제를 해결하기 위해 스프링 프레임워크는 프록시 빈이라는 개념을 제공한다.
📓 proxy-target-class 속성
: 해당 속성을 false 로 하면 스프링 컨테이너는 표준 JDK 인터페이스 기반 프록시를 생성한다.
📓 prototype scope bean 에서 설정
: 공유된 proxy 에서 메소드 호출이 일어날 때 마다 새로운 타겟 instance 가 생성되고 호출이 해당 instance 로 포워딩된다.
📓 request 나 session bean 에서 설정
: request 나 session bean 의 실제 인스턴스가 아닌 Proxy 객체를 주입하여 request 나 session bean 마다 생성되는 빈을 참조한다.
👩💻 프록시 패턴이란?
: 실제 기능을 수행하는 객체 대신, 가상의 객체를 사용해서 로직의 흐름을 제어하는 디자인 패턴이다.
📓 프록시 패턴의 특징
- 원래 하려던 기능을 수행하며 그 외의 부가적인 작업 등을 수행할 수 있다.
- 비용이 많이 드는 연산을 실제로 필요한 시점에 수행할 수 있다.
- 사용자 입장에서는 프록시 객체나 사용법은 유사하므로 사용성이 좋다.
-- 예시
-- applicationContext.xml
✨ music 은 <aop:scoped-proxy/> 설정하여 다른 객체들이 나온다.
<bean id="movie" class="com.scope2.Movie" scope="prototype"/>
<bean id="music" class="com.scope2.Music" scope="prototype">
<aop:scoped-proxy/>
<!-- <aop:scoped-proxy/> : 다른 객체들이 나옴 -->
</bean>
<bean id="user" class="com.scope2.User">
<property name="movie" ref="movie"/>
<property name="music" ref="music"/>
</bean>
public static void main(String[] args) {
AbstractApplicationContext context =
new GenericXmlApplicationContext("classpath:com/scope2/applicationContext.xml");
try {
User user = context.getBean(User.class);
user.execute();
user.execute();
user.execute(); // movie는 동일객체, music는 다른 객체
System.out.println("-------------------");
Movie movie = context.getBean(Movie.class);
Music music = context.getBean(Music.class);
movie.play();
movie.play(); // 같은 객체
System.out.println("-------------------");
music.play();
music.play(); // 다른 객체
} finally {
context.close();
}
}
'Spring' 카테고리의 다른 글
[spring] 컴포넌트 스캔을 이용한 빈 등록 (0) | 2022.11.09 |
---|---|
[spring] Annotation 기반 Bean 설정 (0) | 2022.11.09 |
[spring] 의존성 주입 - 생성자, setter, 프로퍼티 파일 (0) | 2022.11.09 |
[spring] 주요 인터페이스, 의존성 주입 개념 (0) | 2022.11.08 |
[spring] DI (Dependency Injection) 의존성 주입 (0) | 2022.11.08 |
블로그의 정보
개발자 미니민의 개발로그
mini_min