Springboot - Bean Scope(싱글톤, 프로토타입) ?
2019. 8. 17. 19:31ㆍWeb/Spring
스프링에서 빈을 생성할 때, 기본 전략은 모든 빈이 싱글톤으로 생성된다. 즉, 어디에서든지 빈을 주입받는 다면 동일한 빈을 주입받는 것을 보장한다. 하지만 필요에 따라서 빈 주입마다 새로운 빈을 생성해야할 필요가 있을 경우도 있다. 이럴 경우에는 빈 생성시 Scope를 prototype으로 주면 빈 주입마다 새로운 인스턴스가 생성되는 것을 보장한다. 하지만 프로토타입 빈을 사용할 경우 주의해야 할 상황이 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Component
public class ABean {
@Autowired
private BBean b;
public void bMethod() {
b.print();
}
}
@Component
@Scope("prototype")
public class BBean {
public void print() {
System.out.println("BBean !");
}
}
|
cs |
이런식으로 사용한다면 어떻게 될까? 이것은 사실 프로토타입을 쓰나마나이다. 싱글톤으로 생성된 A빈에 프로토타입 B빈을 주입해봤자 A빈은 더이상 생성되지 않기 때문에 항상 동일한 B빈을 사용하게 되는 것이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
@Component
public class ABean {
@Autowired
private BBean b;
public void print() {
System.out.println(b.hashCode());
}
}
@Component
@Scope("prototype")
public class BBean {
}
@Component
public class CBean {
@Autowired
private ABean a;
public void print() {
a.print();
}
}
@Component
public class DBean {
@Autowired
private ABean a;
public void print() {
a.print();
}
}
@SpringBootApplication
public class CircularReferenceApplication implements CommandLineRunner{
@Autowired private CBean c;
@Autowired private DBean d;
public static void main(String[] args) {
SpringApplication.run(CircularReferenceApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
c.print();
d.print();
}
}
|
cs |
위 코드를 실행시켜보자. 프로토타입 빈으로 등록된 B빈이지만 항상 어디서든 동일한 해시코드를 반환한다. 즉, 프로토타입빈을 사용하기 위해서는 아래와 같이 사용하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
@Component
public class ABean {
public void print() {
BBean b = BeanUtil.getBean(BBean.class);
System.out.println(b.hashCode());
}
}
|
cs |
ApplicationContext 객체에서 직접 빈을 가져와서 메소드 내부에서 사용하도록 하자. 이제는 매번 다른 B빈의 해시코드를 반환할 것이다.
2019/02/25 - [Web/Spring] - Spring - ApplicationContext,ApplicationContextAware, 빈이 아닌 객체에 빈주입할때!
'Web > Spring' 카테고리의 다른 글
Spring - Model Validation 방법!(파라미터 Validation),@Valid (0) | 2019.09.10 |
---|---|
Spring - @RequestParam, @ModelAttribute의 차이점? (0) | 2019.09.10 |
Spring - Field vs Constructor vs Setter Injection 그리고 순환참조(Circular Reference) (3) | 2019.08.17 |
Springboot - DB Datasource 암호화/복호화(application.properties) (0) | 2019.08.05 |
Springboot - Logback 설정 방법 !(logback-spring.xml) (1) | 2019.06.15 |