인프런 커뮤니티 질문&답변

준영님의 프로필 이미지
준영

작성한 질문수

스프링 핵심 원리 - 기본편

스코프와 프록시

prototype scope에 proxy를 사용했을 경우 실패하는 이유가 뭔가요?

작성

·

365

1

package hello.core.scope;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Provider;

import static org.assertj.core.api.Assertions.assertThat;

public class SingletonWithPrototypeTest2 {

@Test
void singletonClientUsePrototype() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ClientBean.class, PrototypeBean.class);
ClientBean clientBean1 = ac.getBean(ClientBean.class);
int count1 = clientBean1.logic();
assertThat(count1).isEqualTo(1);

ClientBean clientBean2 = ac.getBean(ClientBean.class, PrototypeBean.class);
int count2 = clientBean2.logic();
assertThat(count2).isEqualTo(1);
}

@Scope("singleton")
static class ClientBean {
@Autowired
private PrototypeBean prototypeBean;

public int logic() {
PrototypeBean prototypeBean1 = prototypeBean;
prototypeBean1.addCount();
int count = prototypeBean1.getCount();
return count;
}
}

@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
static class PrototypeBean {
private int count = 0;

public void addCount() {
System.out.println("count = " + count + " : " + this);
count++;
}

public int getCount() {
System.out.println("count = " + count + " : " + this);
return count;
}

@PostConstruct
public void init() {
System.out.println("PrototypeBean.init " + this);
}

@PreDestroy
public void destroy() {
System.out.println("PrototypeBean.destroy");
}
}
}

 

1, ProxyMode를 사용했을 경우 addCount() 와 getCount() 호출 시 같은 PrototypeBean을 사용하게 할 순 없나요?

2. 위에서 addCount() 와 getCount() 호출 시 다른 PrototypeBean이 생성되는 이유가 무엇인가요?

답변 1

2

안녕하세요. 준영님, 공식 서포터즈 David입니다.

1. 없습니다. 프록시모드를 사용하지 않거나 스코프를 변경해야 합니다.

2. 프록시 모드를 사용하면 내부적으로 target(프록시 객체가 아닌 실제 객체)을 빈팩토리로부터 찾아서 명령을 수행하도록 구현되어 있습니다.

이때, 프로토타입 스코프를 가진 빈을 빈팩토리로부터 찾는 과정에서 프로토타입 스코프의 특성에 따라 매번 새로운 객체가 생성되어 반환됩니다.

따라서 메서드 호출시마다 새로운 객체가 생성되는 것입니다.

감사합니다.

준영님의 프로필 이미지
준영
질문자

감사합니다. 이해가됐어요!

준영님의 프로필 이미지
준영

작성한 질문수

질문하기