IoC Container - Bean의 Scope
Scope type
-
Singleton (Default)
- App에서 1개의 인스턴스만 존재
-
Proto
- 매번 다른 인스턴스 생성
Singleton과 Proto를 만들어서 눈으로 확인해보자.
의존성 없이 사용할 땐 별다른 문제가 없지만,
Singleton과 Proto 사이 의존 관계가 있다면 의도대로 작동하지 않을 수 있다.
Example 1
- Singleton
@Component
class Singleton { }
- Prototype
@Component @Scope(“prototype”)
class Prototype { }
- AppRunner (결과 확인용)
@Component
public class AppRunner implements ApplicationRunner {
@Autowired Singleton singleton;
@Autowired Prototype prototype;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(singleton);
System.out.println(singleton);
System.out.println(prototype);
System.out.println(prototype);
}
}
- ApplicationRunner는 프로그램이 구동되면 run 메소드를 실행한다.
위의 코드를 실행하면 아래와 같은 결과를 볼 수 있다.
com.example.demo.Singleton@6e01f9b0
com.example.demo.Singleton@6e01f9b0
com.example.demo.Prototype@658c5a19
com.example.demo.Prototype@421e361
Singleton은 같은 인스턴스, Prototype은 매번 다른 인스턴스를 생성한다.
Example 2
위의 코드에서 Singleton, AppRunner를 약간 변형한다.
- Singleton이 Prototype를 의존하도록 하였다.
@Component
public class Singleton {
@Autowired private Prototype prototype;
public Prototype getPrototype() {
return prototype;
}
}
- AppRunner에서는 Prototype 출력 부분을 변경했다.
@Component
public class AppRunner implements ApplicationRunner {
@Autowired Singleton singleton;
@Autowired Prototype prototype;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(singleton);
System.out.println(singleton);
System.out.println(singleton.getPrototype());
System.out.println(singleton.getPrototype());
}
}
Example 1과 같은 결과가 나와야 할 것 같지만 전혀 다르게 동작한다.
com.example.demo.Singleton@a307a8c
com.example.demo.Singleton@a307a8c
com.example.demo.Prototype@6e01f9b0
com.example.demo.Prototype@6e01f9b0
Singleton에서 의존하는 Prototype은 마치 Singleton처럼 작동하고 있다.
아래의 Example 3는 위의 Prototype을 원래 생각하던 것처럼 작동하게 만드는 예제이다.
Example 3
Singleton과 의존 관계에 있는 Prototype을 의도대로 작동시키기 위해 코드를 약간 수정한다.
@Component
@Scope(value = “prototype”, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Prototype { }
다시 실행시키면 Singleton에서 참조하는 Prototype도 매번 변경됨을 확인할 수 있다.
com.example.demo.Singleton@3406472c
com.example.demo.Singleton@3406472c
com.example.demo.Prototype@7cbd9d24
com.example.demo.Prototype@1672fe87
원리는 proxy 패턴이다.
본래 Singleton -> Prototype의 관계였으나 proxy가 관여하여 Singleton -> proxy -> Prototype 관계로 바뀌게 된다.
Singleton이 Spring에 의해 생성된 proxy를 참조하고, proxy는 매번 다른 Prototype을 생성하여 반환한다.
작성한 소스코드는 아래 링크에서 볼 수 있다.
https://github.com/dhmin5693/Spring-core-study/tree/master/BeanScope
'Java > Spring framework' 카테고리의 다른 글
Spring framework core (5) - Message Source (0) | 2020.01.12 |
---|---|
Spring framework core (4) - Environment (0) | 2020.01.12 |
Spring framework 소스 코드 읽어보기 - Bean 생성 원리 (1) (0) | 2020.01.06 |
Spring framework core (2) - ApplicationContext (0) | 2020.01.05 |
Spring framework core (1) IoC Container와 Bean (0) | 2020.01.05 |