일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Today
- Total
- ComponentScan
- 의존관계 주입
- docker
- 스프링 싱글톤
- RequiredArgsConstructor
- 생성자 주입
- 객체지향
- springsecurity
- DI컨테이너
- 스프링 Configuration
- beandefinition
- Spring interceptor
- Servlet Filter
- autowired
- 스프링
- 싱글톤 컨테이너
- DI
- UsernamePasswordAuthenticationFilter
- 라즈베리파이
- 스프링 컨테이너
- 롬복 Qualifier
- qualifier
- 라즈베리파이4
- 스프링 빈 조회
- 빈 중복 오류
- 스프링 빈
- Autowired 옵션
- HandlerMethodArgumentResolver
- 도커
- Spring
그날그날 공부기록
스프링의 @Configuration과 싱글톤 본문
@Configuration
public class AppConfig {
@Bean
public MemberService memberService(){
System.out.println("call AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService(){
System.out.println("call AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
System.out.println("call AppConfig.memberRepository");
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy(){
return new FixDiscountPolicy();
}
}
위 설정 파일에서 memberRepository()는 여러 번 호출된다.
그렇다면 new로 MemoryMemberRepository가 여러 번 만들어질 텐데 싱글톤이 어떻게 유지될까?
실제로 여러번 호출되는지 확인하기 위해 프린트 코드를 넣었다.
우선 같은 인스턴스인지 확인해 보기 위해서 테스트 코드를 작성해보았다.
public class ConfigSingletonTest {
@Test
void configTest(){
AnnotationConfigApplicationContext 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("memberService -> memberRepository = " + memberRepository1);
System.out.println("orderService -> memberRepository = " + memberRepository2);
System.out.println("memberRepository -> memberRepository = " + memberRepository);
Assertions.assertThat(memberRepository1).isSameAs(memberRepository2);
}
}
스프링 컨테이너에서 memberRepository를 사용하는 빈을 꺼내고 각 빈에서 사용되는 memberRepository 인스턴스를 반환해 출력해보았다.(구현체에 getMemberRepository라는 메서드를 만들어두었다.)
모두 같은 인스턴스라는걸 확인할 수 있다.
콘솔에서 출력되는 내용도 확인해보았다.
AppConfig에는 memberRepository()는 3번 호출되는데 정작 실제로 호출되는 횟수는 한 번인걸 확인할 수 있다.
스프링이 어떻게 싱글톤을 유지하는지 확인하기 위해 AppConfig 빈을 출력해보았다.
순수한 AppConfig 빈이 아닌 EnhancerBySpringCGLIB라는 것이 출력된다.
설정 파일에 @Configuration이 붙으면 스프링은 싱글톤을 보장하기 위해 CGLIB을 통해 바이트 코드를 조작한다.
→ @Bean이 붙은 메서드마다 스프링 빈이 존재하면 해당 스프링 빈 반환 && 존재하지 않는다면 스프링 빈에 등록하고 반환
그렇게 AppConfig를 상속하는 새로운 클래스를 만들고, 그것을 Bean에 등록한다.
(해당 클래스는 AppConfig의 자식 클래스이므로 AppConfig타입으로 조회가 가능하다.)
만약 설정 파일에 @Configuration이 붙지 않으면 CGLIB을 통해 코드를 조작하지 않고 순수한 AppConfig가 빈으로 등록된다.
당연하지만 싱글톤은 보장되지 않는다!
@Autowired를 통해 해결할 수 있긴 하지만 꼭 필요한 경우가 아니라면 그냥 설정파일에는 @Configuration을 쓰자.
출처 - 김영한님 스프링 강의!
'Spring 공부' 카테고리의 다른 글
스프링의 의존관계 주입 방법 (0) | 2022.07.26 |
---|---|
@ComponentScan & @Autowired에 대하여 (0) | 2022.07.22 |
싱글톤 방식의 주의점 (0) | 2022.07.21 |
싱글톤 컨테이너 (0) | 2022.07.19 |
BeanDefinition (0) | 2022.07.18 |