Spring에서 Bean을 언제 만들지?
그때 그때 상황(Context, Configuration Metadata)에 따라 다릅니다.
0. default로 BeanFactory와[footnote]김재호님의 제보로 수정합니다. BeanFactory는 무조건 Lazy Initialization을 사용합니다.[/footnote] ApplicationContext를 만들 때 모든 bean들의 객체를 만들어 두고 getBean()이라는 요청이 오면 해당 bean을 넘겨 줍니다.
1. 만약에 어떤 bean을 미리 만들어 두기 싫고 필요할 때 만들고 싶다면(lazy-initialization) lazy-init 속성을 사용할 수 있습니다.
2. bean의 scope와도 관계가 있는데요. bean을 정의할 때 별다른 설정을 하지 않으면 singleton scope을 가지게 됩니다. 이 때도 역시 bean을 미리 만들어 둘려고 합니다. singleton이 아닌 scope으로 설정하면 미리 만들어 두지 않습니다.
3. 1번과 2번으로 해당 bean을 설정해도 예상과 다르게 동작할 수 있습니다. scope이나 lazy-init 속성이 다른 여러 bean들 사이의 종속성으로 인해 그런 일이 발생합니다.
0, 1, 2를 표로 나타내면 다음과 같습니다.
bean설정 내용 |
Singleton(Default) |
Non-Singleton |
Lazy-Init=“false”(default) |
초기에 생성 |
나중에 생성 |
Lazy-Init=“true” |
나중에 생성 |
나중에 생성 |
테스트 코드
System.out.println("*******************************");
System.out.println("BeanFactory 만들기 시작!!!");
System.out.println("*******************************");
Resource resource = new ClassPathResource("bean/beanInstantiation-context.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
assertNotNull(beanFactory);
System.out.println("*******************************");
System.out.println("BeanFactory 만들기 끝!!!");
System.out.println("*******************************");
Object bean1 = beanFactory.getBean("bean1");
System.out.println("*******************************");
System.out.println("bean1 만들기 끝!!!");
System.out.println("*******************************");
bean1 = beanFactory.getBean("bean1");
System.out.println("*******************************");
System.out.println("bean1 만들기 끝!!!");
System.out.println("*******************************");
}
예상[footnote]BeanFactory에서만 prototype일 경우 lazy-init을 무시한다.[/footnote]했던 거랑은 달리 ApplicationContext랑 BeanFactory 차이가 없습니다.[footnote]그러나 테스트 해본 결과 ApplicationContext도 prototype일 경우 lazy-init을 무시합니다.[/footnote]
테스트 할 때 사용한 파일들 입니다.
dm225.java
dm224.xml
cm241.properties