Bean의 scope

IOC를 처음 다뤘을 때,(https://velog.io/@max9106/Spring-IOC%EB%AF%B8%EC%99%84), Bean의 scope에 대해 잠깐 다뤘던적이 있다.

이때까지 우리가 사용해 왔던 Bean들은 모두 싱글톤타입의 bean들이었다.(Default 값이 싱글톤이기 때문)

싱글톤이란 어플리케이션 전반에 해당 Bean의 인스턴스가 하나 뿐이라는 뜻이다.(대부분 싱글톤을 사용한다.)

만약 아래와 같이 두 개의 Bean이 있을 때,
스크린샷 2020-01-20 오후 9.20.46.png

스크린샷 2020-01-20 오후 9.20.40.png

그냥 Proto나 Single.getProto()를 하나 둘 다 똑같은 Proto를 지칭하는 것이다(싱글톤이기 때문)

프로토타입은 매번 새로운 인스턴스를 만들어서 사용하는 것이다.
프로토타입으로 scope를 바꾸려면 @Scope("prototype")이라는 어노테이션을 붙여줘야한다.

스크린샷 2020-01-20 오후 9.25.34.png

이렇게 해주면, 사용할 때 마다 매번 다른 인스턴스를 생성한다.

프로토 타입의 bean이 싱글톤 타입의 bean을 참조하는 경우

Proto라는 bean은 매번 다른 인스턴스로 생성되지만, 참조하고 있는 Single은 매번 같은 인스턴스이므로 아무 문제가 없다.

스크린샷 2020-01-20 오후 9.29.38.png

싱글톤 타입의 bean이 프로토 타입의 bean을 참조하는 경우

Single이라는 bean은 싱글톤타입이므로 단 한 번만 만들어진다. 한 번 만들어 질 때 참조하고 있는 프로토 타입의 property도 같이 세팅이된다. 따라서 이 경우는 Single이 참조하고 있는 Proto의 값이 변경되지 않는다.(Proto가 프로토타입 임에도 불구하고)

스크린샷 2020-01-20 오후 9.33.35.png

해결 방법

만약 이러한 문제를 해결하려면(Proto 인스턴스를 업데이트 하려면) 여러 가지 방법이 있다.
1. proxyMode 설정

스크린샷 2020-01-20 오후 9.36.50.png

Proto라는 bean을 proxy로 감싸라고 알려주는 역할(.TARGET_CLASS는 클래스 기반의 proxy를 뜻함)
다른 bean들이 Proto를 사용할 때, 이 bean을 감싸고 있는 proxy bean을 사용하게 하라는 의미

다른 인스턴스(single)들이 proto 타입의 scope의 빈을 직접 참조하면 안되기 때문이다.(직접 참조하면, 매번 다른 인스턴스를 생성하지 못함)

즉, proxy bean이 bean으로 등록되고, 주입도 역시 proxy bean을 해주는 것이다.(proxy도 타입은 같기 때문에 주입해 줄 수 있는 것이다.)

  1. Object Provider

스크린샷 2020-01-20 오후 9.45.23.png

참조하는 곳에서 ObjectProvider을 사용하여 프로토타입의 빈을 세팅해주면, proto 인스턴스가 업데이트 된다.

주의할점

싱글톤 객체 사용시 하나의 인스턴스만 생성되므로, 객체 내부에 변수 값이 존재할 경우, 여러 곳에서 그 값을 고치면(멀티 쓰레드), 안전하지 못하다.(쓰레드 A가 number 값을 1로 바꾸고, 쓰레드 B가 number값을 2로 바꿨다고 가정하면, A가 number 값을 쓰려고 가져온 값이 2가 되어있을수도 있다.)

스크린샷 2020-01-20 오후 9.50.32.png

0개의 댓글