📖 ✏️
- TIL 시리즈에 작성된 글은 '매일 매일 학습한 지식 조각을 메모해 놓은 포스팅'입니다. 공유가 아닌 개인적인 학습 내용 기록을 목적으로 작성되었음을 알려드립니다.
 - 그 외 시리즈에 작성된 공유 목적의 포스팅은 시간이 날 때마다 별도로 작성하고 있습니다. 주로, TIL 시리즈에 작성된 내용에서 특정 주제를 선정하고, 더 깊이 공부한 후 정리하여 작성합니다.
 
자바 코드를 이용한 DI 방식에서 AppConfig는 애플리케이션의 의존 관게 주입과 인스턴스 생성을 담당했다. 스프링으로 전환하는 첫번째 단계로 AppConfig에 설정을 구성한다는 뜻의 @Configuration을 추가하고, 각 메서드에 @Bean을 붙여준다. 이렇게 하면 스프링 컨테이너가 AppConfig의 모든 메서드를 실행하고 반환되는 인스턴스를 스프링 빈으로 등록한다.
package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPoliocy;
import hello.core.discount.RateDiscountPolicy;
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() {
        return new MemberServiceImpl(memberRepository());
    }
    @Bean
    public MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
    @Bean
    public DiscountPolicy discountPolicy() {
        //return new FixDiscountPoliocy();
        return new RateDiscountPolicy(); // 기획자가 배우를 변경하듯, 할인 정책을 변경한다.
    }
}
다음으로 기존에 AppConfig 객체를 직접 생성하여 사용했던 MemberApp 클래스를 아래와 같이 변경한다.
public class MemberApp {
    public static void main(String[] args) {
        // AppConfig appConfig = new AppConfig();
        // MemberService memberService = appConfig.memberService();
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
    }
}
그리고 실행을 해보면 아래와 같은 메시지를 확인할 수 있다.

추가로 OrderApp 클래스도 스프링을 이용하는 방식으로 변경할 수 있다. 아래와 같이 코드를 변경하면 스프링 컨테이너가 관리하는 AppConfig의 모든 인스턴스를 사용할 수 있다.
public class OrderApp {
    public static void main(String[] args) {
        // AppConfig appConfig = new AppConfig();
        // MemberService memberService = appConfig.memberService();
        // OrderService orderService = appConfig.orderService();
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        OrderService orderService = applicationContext.getBean("orderService", OrderService.class);
    }
}