복붙노트

[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