공부/Spring

[스프링 핵심](3) 회원, 주문과 할인 예제를 스프링으로 전환

다음에바꿔야지 2024. 1. 7. 15:33

지금까지 작성한 순수 자바 코드를 스프링으로 전환해보자.

 

AppConfig 수정

package hello.core;

import hello.core.discount.DiscountPolicy;
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.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@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 RateDiscountPolicy();
    }
}

ApppConfig에 @Configuration을 붙여 애플리케이션 설정을 구성한다는 것을 알려준다.

각 메서드에는 @Bean을 붙여 스프링 컨테이너에 스프링 빈으로 등록한다.

 

MemberApp에 스프링 컨테이너 적용

package hello.core;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

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);

        Member member = new Member(1L, "memberA", Grade.VIP);
        memberService.join(member);
        Member findMember = memberService.findMember(1L);
        System.out.println("new member = " + member.getName());
        System.out.println("find Member = " + findMember.getName());
    }
}

 

OrderApp에 스프링 컨테이너 적용

package hello.core;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.order.Order;
import hello.core.order.OrderService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

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);

        long memberId = 1L;
        Member member = new Member(memberId, "memberA", Grade.VIP);
        memberService.join(member);
        Order order = orderService.createOrder(memberId, "itemA", 10000);
        System.out.println("order = " + order);
    }
}

위 두 코드의 변경을 통해, 기존에는 AppConfig를 사용해서 직접 객체를 생성하고 DI를 했지만, 이제부터는 스프링 컨테이너를 통해 사용한다.

ApplicationContext를 스프링 컨테이너라고 한다.

스프링 컨테이너는 @Configuration이 붙은 AppConfig를 설정(구성) 정보로 사용한다. @Bean이 붙은 메서드를 모두 호출해 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.

이제부터 필요한 객체를 applicationContext.getBean()메서드를 통해 찾아야 한다.

 

 

<스프링 컨테이너 생성 과정>

1. new AnnotationconfigApplicatonContext(AppConfig.class)

를 통해 스프링 컨테이너를 생성하면서 구성 정보(AppConfig.class)를 지정해준다.

2. AppConfig.class 내 설정 정보를 사용해서 스프링 빈을 등록한다.

3. 스프링 컨테이너에서 스프링 빈의 의존관계 설정을 준비한다.

4. 스프링 컨테이너는 설정 정보를 참고해 의존관계를 주입(DI)한다.

스프링 컨테이너 세팅 완료!