@Configuration
먼저 각각의 빈들은 @Configuration이 있든 없든 싱글톤으로 유지된다.
@Configuration
어노테이션을 사용하지 않고@Bean
으로만 사용한다면, 스프링 컨테이너에는 등록이 되지만SpringCGLIB
클래스가 자식으로 등록이 되지 않아 대부분의 싱글톤 기능을 모두 잃게 된다. 무슨 의미일까? 아래를 참고해보자.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
System.out.println("call AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
System.out.println("call AppConfig.memberRepository");
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
System.out.println("call AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy() {
//return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
@Test
void configurationTest() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);
MemberRepository memberRepository1 = memberService.getMemberRepository();
MemberRepository memberRepository2 = orderService.getMemberRepository();
System.out.println("memberRepository1 = " + memberRepository1);
System.out.println("memberRepository2 = " + memberRepository2);
System.out.println("memberRepository = " + memberRepository);
assertThat(memberRepository1).isSameAs(memberRepository2).isSameAs(memberRepository);
}
call AppConfig.memberService
call AppConfig.memberRepository
call AppConfig.orderService
memberRepository1 = hello.core.member.MemoryMemberRepository@47da3952
memberRepository2 = hello.core.member.MemoryMemberRepository@47da3952
memberRepository = hello.core.member.MemoryMemberRepository@47da3952
memberService()
,orderService()
와 같이 내부에memberRepository()
가 여러 곳에서 호출되어
new MemoryMemberRepository()
가 호출되어 여러개의 객체가 생성될 때
@Configuration
이 없다면 서로 다른 여러개의 객체가 생성된다.
하지만 @Configuration
애노테이션이 있다면 memberRepository()
와 같은 메서드 호출을 중간에 가로챌 수 있다.
해당 코드가 바로 호출 되는 것이 아니라 스프링 컨테이너에 이미 인스턴스가 생성되어있다면
컨테이너를 이용하여 스프링 빈을 찾아오게 된다.
결과적으로 MemoryMemberRepository
객체는 딱 1개만 생성되어 사용된다.
@Configuration
를 사용하지 않는다면 스프링 컨테이너에서 관리하지 않는다.memberRepository()
처럼 의존관계 주입이 필요해서 메서드를 직접 호출 할 때 싱글톤을 보장하지 않는다.
- 스프링 설정 정보는 항상
@Configuration
을 사용하면 된다.
'Study > Spring' 카테고리의 다른 글
Spring. 스코프와 프록시 (1) | 2024.09.08 |
---|---|
Spring. ObjectProvider (0) | 2024.09.08 |
Spring. 입문 (0) | 2024.08.16 |