[SPRING] 봄 스코프 프록시는 무엇입니까?
SPRING봄 스코프 프록시는 무엇입니까?
우리가 알다시피 봄 (예를 들어 @Transactional 및 @Scheduled) 기능을 추가하는 프록시를 사용합니다. CGLIB 코드 생성기를 사용하여 자식 클래스를 JDK가 동적 프록시 (클래스가 비어 있지 않은 인터페이스를 구현한다)를 사용하여, 또는 생성 - 두 가지 옵션이 있습니다. 나는 항상 프록시 모드가 나를 JDK 동적 프록시와 CGLIB 사이에서 선택할 수 있습니다 생각했다.
하지만 내 가정이 잘못된 것을 보여주는 예제를 만들 수 있었다 :
하나씩 일어나는 것:
@Service
public class MyBeanA {
@Autowired
private MyBeanB myBeanB;
public void foo() {
System.out.println(myBeanB.getCounter());
}
public MyBeanB getMyBeanB() {
return myBeanB;
}
}
원형:
@Service
@Scope(value = "prototype")
public class MyBeanB {
private static final AtomicLong COUNTER = new AtomicLong(0);
private Long index;
public MyBeanB() {
index = COUNTER.getAndIncrement();
System.out.println("constructor invocation:" + index);
}
@Transactional // just to force Spring to create a proxy
public long getCounter() {
return index;
}
}
본관:
MyBeanA beanA = context.getBean(MyBeanA.class);
beanA.foo();
beanA.foo();
MyBeanB myBeanB = beanA.getMyBeanB();
System.out.println("counter: " + myBeanB.getCounter() + ", class=" + myBeanB.getClass());
산출:
constructor invocation:0
0
0
counter: 0, class=class test.pack.MyBeanB$$EnhancerBySpringCGLIB$$2f3d648e
여기서 우리는 두 가지를 볼 수 있습니다
나를 MyBeanB 정의를 수정하자
Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyBeanB {
이 경우에 출력은 :
constructor invocation:0
0
constructor invocation:1
1
constructor invocation:2
counter: 2, class=class test.pack.MyBeanB$$EnhancerBySpringCGLIB$$b06d71f2
여기서 우리는 두 가지를 볼 수 있습니다
당신은 무슨 일이 일어나고 있는지 설명 할 수 있을까요? 프록시 모드는 정말 어떻게 작동합니까?
나는 설명서를 읽었습니다 :
/**
* Specifies whether a component should be configured as a scoped proxy
* and if so, whether the proxy should be interface-based or subclass-based.
* <p>Defaults to {@link ScopedProxyMode#DEFAULT}, which typically indicates
* that no scoped proxy should be created unless a different default
* has been configured at the component-scan instruction level.
* <p>Analogous to {@code <aop:scoped-proxy/>} support in Spring XML.
* @see ScopedProxyMode
*/
그러나 그것은 나를 위해 명확하지 않다.
난 MyBeanB에서 인터페이스를 추출하는 하나 이상의 사건을 조사 하였다 :
public interface MyBeanBInterface {
long getCounter();
}
@Service
public class MyBeanA {
@Autowired
private MyBeanBInterface myBeanB;
@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
public class MyBeanB implements MyBeanBInterface {
이 경우에 출력은 :
constructor invocation:0
0
constructor invocation:1
1
constructor invocation:2
counter: 2, class=class com.sun.proxy.$Proxy92
여기서 우리는 두 가지를 볼 수 있습니다
해결법
from https://stackoverflow.com/questions/58170627/what-is-a-scoped-proxy-in-spring by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄 보안 - 페이지를 로그인 매개 변수를 전달 (0) | 2019.10.03 |
---|---|
[SPRING] POJO가 인스턴스 변수로 JSON 필드를 포장 (0) | 2019.10.03 |
[SPRING] 인터페이스 나 TARGET_CLASS : 나는 프록시 모드를 선택해야합니까? (0) | 2019.10.01 |
[SPRING] 어떤 범위 프록시 봄에? (0) | 2019.10.01 |
[SPRING] 스프링 프레임 워크에서 CGLIB는 무엇입니까? [닫은] (0) | 2019.10.01 |