AppConfig에 호출 로그 남기기
package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
//1번
System.out.println("call AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
//1번
System.out.println("call AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
//2번? 3번?
System.out.println("call AppConfig.memberRepository");
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
스프링 컨테이너가 각각 @Bean을 호출에서 스프링 빈을 생성한다.
memberRepository()는
1 스프링 컨테이너가 스프링 빈에 등록하기 위해 @Bean에서 호출
2. memberService() 로직에서 호출
3. orderService() 로직에서 호출
총 3번이지만 1번만 호출된다.
그 이유는 @Configuration을 적용한 AppConfig 때문이다.
@Test
void configutrationDeep() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
//AppConfig도 스프링 빈으로 등록딘다.
AppConfig bean = ac.getBean(AppConfig.class);
System.out.println("bean = " + bean.getClass());
// 출력: bean class.hello.core.AppConfig$$EnhancerBySpringCHLIB$$~~
}
AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들고
이 클래스를 스프링 빈으로 등록한 것이다.
스프링 빈이 없으면 생성해서 스프링 빈으로 등록 후 반환하도록 되어
임의의 다른 클래스가 싱글톤이 보장되도록 한다.
@Configuration을 적용하지 않고 @Bean만 사용하면
처음 예상대로 3번다 호출되면서 싱글톤이 보장되지 않는다
'Spring' 카테고리의 다른 글
[Spring] 컴포넌트 스캔 (0) | 2025.07.14 |
---|---|
[Spring] 싱글톤 방식의 주의점 (1) | 2025.06.09 |
[Spring] 스프링 빈 (1) | 2025.01.20 |
[Spring] 스프링 컨테이너 (0) | 2025.01.08 |
[Spring] 객체 지향 원리 적용 - Appconfig 리팩터링 (0) | 2024.12.24 |